12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243 |
- /** @file
- DnsDxe support functions implementation.
- Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "DnsImpl.h"
- /**
- Remove TokenEntry from TokenMap.
- @param[in] TokenMap All DNSv4 Token entrys.
- @param[in] TokenEntry TokenEntry need to be removed.
- @retval EFI_SUCCESS Remove TokenEntry from TokenMap sucessfully.
- @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
- **/
- EFI_STATUS
- Dns4RemoveTokenEntry (
- IN NET_MAP *TokenMap,
- IN DNS4_TOKEN_ENTRY *TokenEntry
- )
- {
- NET_MAP_ITEM *Item;
- //
- // Find the TokenEntry first.
- //
- Item = NetMapFindKey (TokenMap, (VOID *) TokenEntry);
- if (Item != NULL) {
- //
- // Remove the TokenEntry if it's found in the map.
- //
- NetMapRemoveItem (TokenMap, Item, NULL);
- return EFI_SUCCESS;
- }
- return EFI_NOT_FOUND;
- }
- /**
- Remove TokenEntry from TokenMap.
- @param[in] TokenMap All DNSv6 Token entrys.
- @param[in] TokenEntry TokenEntry need to be removed.
- @retval EFI_SUCCESS Remove TokenEntry from TokenMap sucessfully.
- @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
- **/
- EFI_STATUS
- Dns6RemoveTokenEntry (
- IN NET_MAP *TokenMap,
- IN DNS6_TOKEN_ENTRY *TokenEntry
- )
- {
- NET_MAP_ITEM *Item;
- //
- // Find the TokenEntry first.
- //
- Item = NetMapFindKey (TokenMap, (VOID *) TokenEntry);
- if (Item != NULL) {
- //
- // Remove the TokenEntry if it's found in the map.
- //
- NetMapRemoveItem (TokenMap, Item, NULL);
- return EFI_SUCCESS;
- }
- return EFI_NOT_FOUND;
- }
- /**
- This function cancle the token specified by Arg in the Map.
- @param[in] Map Pointer to the NET_MAP.
- @param[in] Item Pointer to the NET_MAP_ITEM.
- @param[in] Arg Pointer to the token to be cancelled. If NULL, all
- the tokens in this Map will be cancelled.
- This parameter is optional and may be NULL.
- @retval EFI_SUCCESS The token is cancelled if Arg is NULL, or the token
- is not the same as that in the Item, if Arg is not
- NULL.
- @retval EFI_ABORTED Arg is not NULL, and the token specified by Arg is
- cancelled.
- **/
- EFI_STATUS
- EFIAPI
- Dns4CancelTokens (
- IN NET_MAP *Map,
- IN NET_MAP_ITEM *Item,
- IN VOID *Arg OPTIONAL
- )
- {
- DNS4_TOKEN_ENTRY *TokenEntry;
- NET_BUF *Packet;
- UDP_IO *UdpIo;
- if ((Arg != NULL) && (Item->Key != Arg)) {
- return EFI_SUCCESS;
- }
- if (Item->Value != NULL) {
- //
- // If the TokenEntry is a transmit TokenEntry, the corresponding Packet is recorded in
- // Item->Value.
- //
- Packet = (NET_BUF *) (Item->Value);
- UdpIo = (UDP_IO *) (*((UINTN *) &Packet->ProtoData[0]));
- UdpIoCancelSentDatagram (UdpIo, Packet);
- }
- //
- // Remove TokenEntry from Dns4TxTokens.
- //
- TokenEntry = (DNS4_TOKEN_ENTRY *) Item->Key;
- if (Dns4RemoveTokenEntry (Map, TokenEntry) == EFI_SUCCESS) {
- TokenEntry->Token->Status = EFI_ABORTED;
- gBS->SignalEvent (TokenEntry->Token->Event);
- DispatchDpc ();
- }
- if (Arg != NULL) {
- return EFI_ABORTED;
- }
- return EFI_SUCCESS;
- }
- /**
- This function cancle the token specified by Arg in the Map.
- @param[in] Map Pointer to the NET_MAP.
- @param[in] Item Pointer to the NET_MAP_ITEM.
- @param[in] Arg Pointer to the token to be cancelled. If NULL, all
- the tokens in this Map will be cancelled.
- This parameter is optional and may be NULL.
- @retval EFI_SUCCESS The token is cancelled if Arg is NULL, or the token
- is not the same as that in the Item, if Arg is not
- NULL.
- @retval EFI_ABORTED Arg is not NULL, and the token specified by Arg is
- cancelled.
- **/
- EFI_STATUS
- EFIAPI
- Dns6CancelTokens (
- IN NET_MAP *Map,
- IN NET_MAP_ITEM *Item,
- IN VOID *Arg OPTIONAL
- )
- {
- DNS6_TOKEN_ENTRY *TokenEntry;
- NET_BUF *Packet;
- UDP_IO *UdpIo;
- if ((Arg != NULL) && (Item->Key != Arg)) {
- return EFI_SUCCESS;
- }
- if (Item->Value != NULL) {
- //
- // If the TokenEntry is a transmit TokenEntry, the corresponding Packet is recorded in
- // Item->Value.
- //
- Packet = (NET_BUF *) (Item->Value);
- UdpIo = (UDP_IO *) (*((UINTN *) &Packet->ProtoData[0]));
- UdpIoCancelSentDatagram (UdpIo, Packet);
- }
- //
- // Remove TokenEntry from Dns6TxTokens.
- //
- TokenEntry = (DNS6_TOKEN_ENTRY *) Item->Key;
- if (Dns6RemoveTokenEntry (Map, TokenEntry) == EFI_SUCCESS) {
- TokenEntry->Token->Status = EFI_ABORTED;
- gBS->SignalEvent (TokenEntry->Token->Event);
- DispatchDpc ();
- }
- if (Arg != NULL) {
- return EFI_ABORTED;
- }
- return EFI_SUCCESS;
- }
- /**
- Get the TokenEntry from the TokensMap.
- @param[in] TokensMap All DNSv4 Token entrys
- @param[in] Token Pointer to the token to be get.
- @param[out] TokenEntry Pointer to TokenEntry corresponding Token.
- @retval EFI_SUCCESS Get the TokenEntry from the TokensMap sucessfully.
- @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
- **/
- EFI_STATUS
- EFIAPI
- GetDns4TokenEntry (
- IN NET_MAP *TokensMap,
- IN EFI_DNS4_COMPLETION_TOKEN *Token,
- OUT DNS4_TOKEN_ENTRY **TokenEntry
- )
- {
- LIST_ENTRY *Entry;
- NET_MAP_ITEM *Item;
- NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {
- Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
- *TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);
- if ((*TokenEntry)->Token == Token) {
- return EFI_SUCCESS;
- }
- }
- *TokenEntry = NULL;
- return EFI_NOT_FOUND;
- }
- /**
- Get the TokenEntry from the TokensMap.
- @param[in] TokensMap All DNSv6 Token entrys
- @param[in] Token Pointer to the token to be get.
- @param[out] TokenEntry Pointer to TokenEntry corresponding Token.
- @retval EFI_SUCCESS Get the TokenEntry from the TokensMap sucessfully.
- @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
- **/
- EFI_STATUS
- EFIAPI
- GetDns6TokenEntry (
- IN NET_MAP *TokensMap,
- IN EFI_DNS6_COMPLETION_TOKEN *Token,
- OUT DNS6_TOKEN_ENTRY **TokenEntry
- )
- {
- LIST_ENTRY *Entry;
- NET_MAP_ITEM *Item;
- NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {
- Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
- *TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);
- if ((*TokenEntry)->Token == Token) {
- return EFI_SUCCESS;
- }
- }
- *TokenEntry =NULL;
- return EFI_NOT_FOUND;
- }
- /**
- Cancel DNS4 tokens from the DNS4 instance.
- @param[in] Instance Pointer to the DNS instance context data.
- @param[in] Token Pointer to the token to be canceled. If NULL, all
- tokens in this instance will be cancelled.
- This parameter is optional and may be NULL.
- @retval EFI_SUCCESS The Token is cancelled.
- @retval EFI_NOT_FOUND The Token is not found.
- **/
- EFI_STATUS
- Dns4InstanceCancelToken (
- IN DNS_INSTANCE *Instance,
- IN EFI_DNS4_COMPLETION_TOKEN *Token
- )
- {
- EFI_STATUS Status;
- DNS4_TOKEN_ENTRY *TokenEntry;
- TokenEntry = NULL;
- if(Token != NULL ) {
- Status = GetDns4TokenEntry (&Instance->Dns4TxTokens, Token, &TokenEntry);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- } else {
- TokenEntry = NULL;
- }
- //
- // Cancel this TokenEntry from the Dns4TxTokens map.
- //
- Status = NetMapIterate (&Instance->Dns4TxTokens, Dns4CancelTokens, TokenEntry);
- if ((TokenEntry != NULL) && (Status == EFI_ABORTED)) {
- //
- // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from
- // the Dns4TxTokens and returns success.
- //
- if (NetMapIsEmpty (&Instance->Dns4TxTokens)) {
- Instance->UdpIo->Protocol.Udp4->Cancel (Instance->UdpIo->Protocol.Udp4, &Instance->UdpIo->RecvRequest->Token.Udp4);
- }
- return EFI_SUCCESS;
- }
- ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns4TxTokens)));
- if (NetMapIsEmpty (&Instance->Dns4TxTokens)) {
- Instance->UdpIo->Protocol.Udp4->Cancel (Instance->UdpIo->Protocol.Udp4, &Instance->UdpIo->RecvRequest->Token.Udp4);
- }
- return EFI_SUCCESS;
- }
- /**
- Cancel DNS6 tokens from the DNS6 instance.
- @param[in] Instance Pointer to the DNS instance context data.
- @param[in] Token Pointer to the token to be canceled. If NULL, all
- tokens in this instance will be cancelled.
- This parameter is optional and may be NULL.
- @retval EFI_SUCCESS The Token is cancelled.
- @retval EFI_NOT_FOUND The Token is not found.
- **/
- EFI_STATUS
- Dns6InstanceCancelToken (
- IN DNS_INSTANCE *Instance,
- IN EFI_DNS6_COMPLETION_TOKEN *Token
- )
- {
- EFI_STATUS Status;
- DNS6_TOKEN_ENTRY *TokenEntry;
- TokenEntry = NULL;
- if(Token != NULL ) {
- Status = GetDns6TokenEntry (&Instance->Dns6TxTokens, Token, &TokenEntry);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- } else {
- TokenEntry = NULL;
- }
- //
- // Cancel this TokenEntry from the Dns6TxTokens map.
- //
- Status = NetMapIterate (&Instance->Dns6TxTokens, Dns6CancelTokens, TokenEntry);
- if ((TokenEntry != NULL) && (Status == EFI_ABORTED)) {
- //
- // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from
- // the Dns6TxTokens and returns success.
- //
- if (NetMapIsEmpty (&Instance->Dns6TxTokens)) {
- Instance->UdpIo->Protocol.Udp6->Cancel (Instance->UdpIo->Protocol.Udp6, &Instance->UdpIo->RecvRequest->Token.Udp6);
- }
- return EFI_SUCCESS;
- }
- ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns6TxTokens)));
- if (NetMapIsEmpty (&Instance->Dns6TxTokens)) {
- Instance->UdpIo->Protocol.Udp6->Cancel (Instance->UdpIo->Protocol.Udp6, &Instance->UdpIo->RecvRequest->Token.Udp6);
- }
- return EFI_SUCCESS;
- }
- /**
- Free the resource related to the configure parameters.
- @param Config The DNS configure data
- **/
- VOID
- Dns4CleanConfigure (
- IN OUT EFI_DNS4_CONFIG_DATA *Config
- )
- {
- if (Config->DnsServerList != NULL) {
- FreePool (Config->DnsServerList);
- }
- ZeroMem (Config, sizeof (EFI_DNS4_CONFIG_DATA));
- }
- /**
- Free the resource related to the configure parameters.
- @param Config The DNS configure data
- **/
- VOID
- Dns6CleanConfigure (
- IN OUT EFI_DNS6_CONFIG_DATA *Config
- )
- {
- if (Config->DnsServerList != NULL) {
- FreePool (Config->DnsServerList);
- }
- ZeroMem (Config, sizeof (EFI_DNS6_CONFIG_DATA));
- }
- /**
- Allocate memory for configure parameter such as timeout value for Dst,
- then copy the configure parameter from Src to Dst.
- @param[out] Dst The destination DHCP configure data.
- @param[in] Src The source DHCP configure data.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
- @retval EFI_SUCCESS The configure is copied.
- **/
- EFI_STATUS
- Dns4CopyConfigure (
- OUT EFI_DNS4_CONFIG_DATA *Dst,
- IN EFI_DNS4_CONFIG_DATA *Src
- )
- {
- UINTN Len;
- UINT32 Index;
- CopyMem (Dst, Src, sizeof (*Dst));
- Dst->DnsServerList = NULL;
- //
- // Allocate a memory then copy DnsServerList to it
- //
- if (Src->DnsServerList != NULL) {
- Len = Src->DnsServerListCount * sizeof (EFI_IPv4_ADDRESS);
- Dst->DnsServerList = AllocatePool (Len);
- if (Dst->DnsServerList == NULL) {
- Dns4CleanConfigure (Dst);
- return EFI_OUT_OF_RESOURCES;
- }
- for (Index = 0; Index < Src->DnsServerListCount; Index++) {
- CopyMem (&Dst->DnsServerList[Index], &Src->DnsServerList[Index], sizeof (EFI_IPv4_ADDRESS));
- }
- }
- return EFI_SUCCESS;
- }
- /**
- Allocate memory for configure parameter such as timeout value for Dst,
- then copy the configure parameter from Src to Dst.
- @param[out] Dst The destination DHCP configure data.
- @param[in] Src The source DHCP configure data.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
- @retval EFI_SUCCESS The configure is copied.
- **/
- EFI_STATUS
- Dns6CopyConfigure (
- OUT EFI_DNS6_CONFIG_DATA *Dst,
- IN EFI_DNS6_CONFIG_DATA *Src
- )
- {
- UINTN Len;
- UINT32 Index;
- CopyMem (Dst, Src, sizeof (*Dst));
- Dst->DnsServerList = NULL;
- //
- // Allocate a memory then copy DnsServerList to it
- //
- if (Src->DnsServerList != NULL) {
- Len = Src->DnsServerCount * sizeof (EFI_IPv6_ADDRESS);
- Dst->DnsServerList = AllocatePool (Len);
- if (Dst->DnsServerList == NULL) {
- Dns6CleanConfigure (Dst);
- return EFI_OUT_OF_RESOURCES;
- }
- for (Index = 0; Index < Src->DnsServerCount; Index++) {
- CopyMem (&Dst->DnsServerList[Index], &Src->DnsServerList[Index], sizeof (EFI_IPv6_ADDRESS));
- }
- }
- return EFI_SUCCESS;
- }
- /**
- Callback of Dns packet. Does nothing.
- @param Arg The context.
- **/
- VOID
- EFIAPI
- DnsDummyExtFree (
- IN VOID *Arg
- )
- {
- }
- /**
- Poll the UDP to get the IP4 default address, which may be retrieved
- by DHCP.
- The default time out value is 5 seconds. If IP has retrieved the default address,
- the UDP is reconfigured.
- @param Instance The DNS instance
- @param UdpIo The UDP_IO to poll
- @param UdpCfgData The UDP configure data to reconfigure the UDP_IO
- @retval TRUE The default address is retrieved and UDP is reconfigured.
- @retval FALSE Some error occured.
- **/
- BOOLEAN
- Dns4GetMapping (
- IN DNS_INSTANCE *Instance,
- IN UDP_IO *UdpIo,
- IN EFI_UDP4_CONFIG_DATA *UdpCfgData
- )
- {
- DNS_SERVICE *Service;
- EFI_IP4_MODE_DATA Ip4Mode;
- EFI_UDP4_PROTOCOL *Udp;
- EFI_STATUS Status;
- ASSERT (Instance->Dns4CfgData.UseDefaultSetting);
- Service = Instance->Service;
- Udp = UdpIo->Protocol.Udp4;
- Status = gBS->SetTimer (
- Service->TimerToGetMap,
- TimerRelative,
- DNS_TIME_TO_GETMAP * TICKS_PER_SECOND
- );
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
- while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {
- Udp->Poll (Udp);
- if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) &&
- Ip4Mode.IsConfigured) {
- Udp->Configure (Udp, NULL);
- return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);
- }
- }
- return FALSE;
- }
- /**
- Configure the opened Udp6 instance until the corresponding Ip6 instance
- has been configured.
- @param Instance The DNS instance
- @param UdpIo The UDP_IO to poll
- @param UdpCfgData The UDP configure data to reconfigure the UDP_IO
- @retval TRUE Configure the Udp6 instance successfully.
- @retval FALSE Some error occured.
- **/
- BOOLEAN
- Dns6GetMapping (
- IN DNS_INSTANCE *Instance,
- IN UDP_IO *UdpIo,
- IN EFI_UDP6_CONFIG_DATA *UdpCfgData
- )
- {
- DNS_SERVICE *Service;
- EFI_IP6_MODE_DATA Ip6Mode;
- EFI_UDP6_PROTOCOL *Udp;
- EFI_STATUS Status;
- Service = Instance->Service;
- Udp = UdpIo->Protocol.Udp6;
- Status = gBS->SetTimer (
- Service->TimerToGetMap,
- TimerRelative,
- DNS_TIME_TO_GETMAP * TICKS_PER_SECOND
- );
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
- while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {
- Udp->Poll (Udp);
- if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip6Mode, NULL, NULL))) {
- if (Ip6Mode.AddressList != NULL) {
- FreePool (Ip6Mode.AddressList);
- }
- if (Ip6Mode.GroupTable != NULL) {
- FreePool (Ip6Mode.GroupTable);
- }
- if (Ip6Mode.RouteTable != NULL) {
- FreePool (Ip6Mode.RouteTable);
- }
- if (Ip6Mode.NeighborCache != NULL) {
- FreePool (Ip6Mode.NeighborCache);
- }
- if (Ip6Mode.PrefixTable != NULL) {
- FreePool (Ip6Mode.PrefixTable);
- }
- if (Ip6Mode.IcmpTypeList != NULL) {
- FreePool (Ip6Mode.IcmpTypeList);
- }
- if (!Ip6Mode.IsStarted || Ip6Mode.IsConfigured) {
- Udp->Configure (Udp, NULL);
- if (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS) {
- return TRUE;
- }
- }
- }
- }
- return FALSE;
- }
- /**
- Configure the UDP.
- @param Instance The DNS session
- @param UdpIo The UDP_IO instance
- @retval EFI_SUCCESS The UDP is successfully configured for the
- session.
- **/
- EFI_STATUS
- Dns4ConfigUdp (
- IN DNS_INSTANCE *Instance,
- IN UDP_IO *UdpIo
- )
- {
- EFI_DNS4_CONFIG_DATA *Config;
- EFI_UDP4_CONFIG_DATA UdpConfig;
- EFI_STATUS Status;
- Config = &Instance->Dns4CfgData;
- UdpConfig.AcceptBroadcast = FALSE;
- UdpConfig.AcceptPromiscuous = FALSE;
- UdpConfig.AcceptAnyPort = FALSE;
- UdpConfig.AllowDuplicatePort = FALSE;
- UdpConfig.TypeOfService = 0;
- UdpConfig.TimeToLive = 128;
- UdpConfig.DoNotFragment = FALSE;
- UdpConfig.ReceiveTimeout = 0;
- UdpConfig.TransmitTimeout = 0;
- UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;
- UdpConfig.SubnetMask = Config->SubnetMask;
- UdpConfig.StationPort = Config->LocalPort;
- UdpConfig.RemotePort = DNS_SERVER_PORT;
- CopyMem (&UdpConfig.StationAddress, &Config->StationIp, sizeof (EFI_IPv4_ADDRESS));
- CopyMem (&UdpConfig.RemoteAddress, &Instance->SessionDnsServer.v4, sizeof (EFI_IPv4_ADDRESS));
- Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfig);
- if ((Status == EFI_NO_MAPPING) && Dns4GetMapping (Instance, UdpIo, &UdpConfig)) {
- return EFI_SUCCESS;
- }
- return Status;
- }
- /**
- Configure the UDP.
- @param Instance The DNS session
- @param UdpIo The UDP_IO instance
- @retval EFI_SUCCESS The UDP is successfully configured for the
- session.
- **/
- EFI_STATUS
- Dns6ConfigUdp (
- IN DNS_INSTANCE *Instance,
- IN UDP_IO *UdpIo
- )
- {
- EFI_DNS6_CONFIG_DATA *Config;
- EFI_UDP6_CONFIG_DATA UdpConfig;
- EFI_STATUS Status;
- Config = &Instance->Dns6CfgData;
- UdpConfig.AcceptPromiscuous = FALSE;
- UdpConfig.AcceptAnyPort = FALSE;
- UdpConfig.AllowDuplicatePort = FALSE;
- UdpConfig.TrafficClass = 0;
- UdpConfig.HopLimit = 128;
- UdpConfig.ReceiveTimeout = 0;
- UdpConfig.TransmitTimeout = 0;
- UdpConfig.StationPort = Config->LocalPort;
- UdpConfig.RemotePort = DNS_SERVER_PORT;
- CopyMem (&UdpConfig.StationAddress, &Config->StationIp, sizeof (EFI_IPv6_ADDRESS));
- CopyMem (&UdpConfig.RemoteAddress, &Instance->SessionDnsServer.v6, sizeof (EFI_IPv6_ADDRESS));
- Status = UdpIo->Protocol.Udp6->Configure (UdpIo->Protocol.Udp6, &UdpConfig);
- if ((Status == EFI_NO_MAPPING) && Dns6GetMapping (Instance, UdpIo, &UdpConfig)) {
- return EFI_SUCCESS;
- }
- return Status;
- }
- /**
- Update Dns4 cache to shared list of caches of all DNSv4 instances.
- @param Dns4CacheList All Dns4 cache list.
- @param DeleteFlag If FALSE, this function is to add one entry to the DNS Cache.
- If TRUE, this function will delete matching DNS Cache entry.
- @param Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
- If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
- @param DnsCacheEntry Entry Pointer to DNS Cache entry.
- @retval EFI_SUCCESS Update Dns4 cache successfully.
- @retval Others Failed to update Dns4 cache.
- **/
- EFI_STATUS
- EFIAPI
- UpdateDns4Cache (
- IN LIST_ENTRY *Dns4CacheList,
- IN BOOLEAN DeleteFlag,
- IN BOOLEAN Override,
- IN EFI_DNS4_CACHE_ENTRY DnsCacheEntry
- )
- {
- DNS4_CACHE *NewDnsCache;
- DNS4_CACHE *Item;
- LIST_ENTRY *Entry;
- LIST_ENTRY *Next;
- NewDnsCache = NULL;
- Item = NULL;
- //
- // Search the database for the matching EFI_DNS_CACHE_ENTRY
- //
- NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns4CacheList) {
- Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
- if (StrCmp (DnsCacheEntry.HostName, Item->DnsCache.HostName) == 0 && \
- CompareMem (DnsCacheEntry.IpAddress, Item->DnsCache.IpAddress, sizeof (EFI_IPv4_ADDRESS)) == 0) {
- //
- // This is the Dns cache entry
- //
- if (DeleteFlag) {
- //
- // Delete matching DNS Cache entry
- //
- RemoveEntryList (&Item->AllCacheLink);
- FreePool (Item->DnsCache.HostName);
- FreePool (Item->DnsCache.IpAddress);
- FreePool (Item);
- return EFI_SUCCESS;
- } else if (Override) {
- //
- // Update this one
- //
- Item->DnsCache.Timeout = DnsCacheEntry.Timeout;
- return EFI_SUCCESS;
- }else {
- return EFI_ACCESS_DENIED;
- }
- }
- }
- //
- // Add new one
- //
- NewDnsCache = AllocatePool (sizeof (DNS4_CACHE));
- if (NewDnsCache == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- InitializeListHead (&NewDnsCache->AllCacheLink);
- NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));
- if (NewDnsCache->DnsCache.HostName == NULL) {
- FreePool (NewDnsCache);
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));
- NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv4_ADDRESS));
- if (NewDnsCache->DnsCache.IpAddress == NULL) {
- FreePool (NewDnsCache->DnsCache.HostName);
- FreePool (NewDnsCache);
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv4_ADDRESS));
- NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;
- InsertTailList (Dns4CacheList, &NewDnsCache->AllCacheLink);
- return EFI_SUCCESS;
- }
- /**
- Update Dns6 cache to shared list of caches of all DNSv6 instances.
- @param Dns6CacheList All Dns6 cache list.
- @param DeleteFlag If FALSE, this function is to add one entry to the DNS Cache.
- If TRUE, this function will delete matching DNS Cache entry.
- @param Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
- If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
- @param DnsCacheEntry Entry Pointer to DNS Cache entry.
- @retval EFI_SUCCESS Update Dns6 cache successfully.
- @retval Others Failed to update Dns6 cache.
- **/
- EFI_STATUS
- EFIAPI
- UpdateDns6Cache (
- IN LIST_ENTRY *Dns6CacheList,
- IN BOOLEAN DeleteFlag,
- IN BOOLEAN Override,
- IN EFI_DNS6_CACHE_ENTRY DnsCacheEntry
- )
- {
- DNS6_CACHE *NewDnsCache;
- DNS6_CACHE *Item;
- LIST_ENTRY *Entry;
- LIST_ENTRY *Next;
- NewDnsCache = NULL;
- Item = NULL;
- //
- // Search the database for the matching EFI_DNS_CACHE_ENTRY
- //
- NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns6CacheList) {
- Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
- if (StrCmp (DnsCacheEntry.HostName, Item->DnsCache.HostName) == 0 && \
- CompareMem (DnsCacheEntry.IpAddress, Item->DnsCache.IpAddress, sizeof (EFI_IPv6_ADDRESS)) == 0) {
- //
- // This is the Dns cache entry
- //
- if (DeleteFlag) {
- //
- // Delete matching DNS Cache entry
- //
- RemoveEntryList (&Item->AllCacheLink);
- FreePool (Item->DnsCache.HostName);
- FreePool (Item->DnsCache.IpAddress);
- FreePool (Item);
- return EFI_SUCCESS;
- } else if (Override) {
- //
- // Update this one
- //
- Item->DnsCache.Timeout = DnsCacheEntry.Timeout;
- return EFI_SUCCESS;
- }else {
- return EFI_ACCESS_DENIED;
- }
- }
- }
- //
- // Add new one
- //
- NewDnsCache = AllocatePool (sizeof (DNS6_CACHE));
- if (NewDnsCache == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- InitializeListHead (&NewDnsCache->AllCacheLink);
- NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));
- if (NewDnsCache->DnsCache.HostName == NULL) {
- FreePool (NewDnsCache);
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));
- NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv6_ADDRESS));
- if (NewDnsCache->DnsCache.IpAddress == NULL) {
- FreePool (NewDnsCache->DnsCache.HostName);
- FreePool (NewDnsCache);
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv6_ADDRESS));
- NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;
- InsertTailList (Dns6CacheList, &NewDnsCache->AllCacheLink);
- return EFI_SUCCESS;
- }
- /**
- Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server.
- @param Dns4ServerList Common list of addresses of all configured DNSv4 server.
- @param ServerIp DNS server Ip.
- @retval EFI_SUCCESS Add Dns4 ServerIp to common list successfully.
- @retval Others Failed to add Dns4 ServerIp to common list.
- **/
- EFI_STATUS
- EFIAPI
- AddDns4ServerIp (
- IN LIST_ENTRY *Dns4ServerList,
- IN EFI_IPv4_ADDRESS ServerIp
- )
- {
- DNS4_SERVER_IP *NewServerIp;
- DNS4_SERVER_IP *Item;
- LIST_ENTRY *Entry;
- LIST_ENTRY *Next;
- NewServerIp = NULL;
- Item = NULL;
- //
- // Search the database for the matching ServerIp
- //
- NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns4ServerList) {
- Item = NET_LIST_USER_STRUCT (Entry, DNS4_SERVER_IP, AllServerLink);
- if (CompareMem (&Item->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS)) == 0) {
- //
- // Already done.
- //
- return EFI_SUCCESS;
- }
- }
- //
- // Add new one
- //
- NewServerIp = AllocatePool (sizeof (DNS4_SERVER_IP));
- if (NewServerIp == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- InitializeListHead (&NewServerIp->AllServerLink);
- CopyMem (&NewServerIp->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS));
- InsertTailList (Dns4ServerList, &NewServerIp->AllServerLink);
- return EFI_SUCCESS;
- }
- /**
- Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server.
- @param Dns6ServerList Common list of addresses of all configured DNSv6 server.
- @param ServerIp DNS server Ip.
- @retval EFI_SUCCESS Add Dns6 ServerIp to common list successfully.
- @retval Others Failed to add Dns6 ServerIp to common list.
- **/
- EFI_STATUS
- EFIAPI
- AddDns6ServerIp (
- IN LIST_ENTRY *Dns6ServerList,
- IN EFI_IPv6_ADDRESS ServerIp
- )
- {
- DNS6_SERVER_IP *NewServerIp;
- DNS6_SERVER_IP *Item;
- LIST_ENTRY *Entry;
- LIST_ENTRY *Next;
- NewServerIp = NULL;
- Item = NULL;
- //
- // Search the database for the matching ServerIp
- //
- NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns6ServerList) {
- Item = NET_LIST_USER_STRUCT (Entry, DNS6_SERVER_IP, AllServerLink);
- if (CompareMem (&Item->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS)) == 0) {
- //
- // Already done.
- //
- return EFI_SUCCESS;
- }
- }
- //
- // Add new one
- //
- NewServerIp = AllocatePool (sizeof (DNS6_SERVER_IP));
- if (NewServerIp == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- InitializeListHead (&NewServerIp->AllServerLink);
- CopyMem (&NewServerIp->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS));
- InsertTailList (Dns6ServerList, &NewServerIp->AllServerLink);
- return EFI_SUCCESS;
- }
- /**
- Find out whether the response is valid or invalid.
- @param TokensMap All DNS transmittal Tokens entry.
- @param Identification Identification for queried packet.
- @param Type Type for queried packet.
- @param Class Class for queried packet.
- @param Item Return corresponding Token entry.
- @retval TRUE The response is valid.
- @retval FALSE The response is invalid.
- **/
- BOOLEAN
- IsValidDnsResponse (
- IN NET_MAP *TokensMap,
- IN UINT16 Identification,
- IN UINT16 Type,
- IN UINT16 Class,
- OUT NET_MAP_ITEM **Item
- )
- {
- LIST_ENTRY *Entry;
- NET_BUF *Packet;
- UINT8 *TxString;
- DNS_HEADER *DnsHeader;
- CHAR8 *QueryName;
- DNS_QUERY_SECTION *QuerySection;
- NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {
- *Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
- Packet = (NET_BUF *) ((*Item)->Value);
- if (Packet == NULL){
- continue;
- } else {
- TxString = NetbufGetByte (Packet, 0, NULL);
- ASSERT (TxString != NULL);
- DnsHeader = (DNS_HEADER *) TxString;
- QueryName = (CHAR8 *) (TxString + sizeof (*DnsHeader));
- QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);
- if (NTOHS (DnsHeader->Identification) == Identification &&
- NTOHS (QuerySection->Type) == Type &&
- NTOHS (QuerySection->Class) == Class) {
- return TRUE;
- }
- }
- }
- *Item = NULL;
- return FALSE;
- }
- /**
- Parse Dns Response.
- @param Instance The DNS instance
- @param RxString Received buffer.
- @param Length Received buffer length.
- @param Completed Flag to indicate that Dns response is valid.
- @retval EFI_SUCCESS Parse Dns Response successfully.
- @retval Others Failed to parse Dns Response.
- **/
- EFI_STATUS
- ParseDnsResponse (
- IN OUT DNS_INSTANCE *Instance,
- IN UINT8 *RxString,
- IN UINT32 Length,
- OUT BOOLEAN *Completed
- )
- {
- DNS_HEADER *DnsHeader;
- CHAR8 *QueryName;
- UINT32 QueryNameLen;
- DNS_QUERY_SECTION *QuerySection;
- CHAR8 *AnswerName;
- DNS_ANSWER_SECTION *AnswerSection;
- UINT8 *AnswerData;
- NET_MAP_ITEM *Item;
- DNS4_TOKEN_ENTRY *Dns4TokenEntry;
- DNS6_TOKEN_ENTRY *Dns6TokenEntry;
- UINT32 IpCount;
- UINT32 RRCount;
- UINT32 AnswerSectionNum;
- UINT32 CNameTtl;
- EFI_IPv4_ADDRESS *HostAddr4;
- EFI_IPv6_ADDRESS *HostAddr6;
- EFI_DNS4_CACHE_ENTRY *Dns4CacheEntry;
- EFI_DNS6_CACHE_ENTRY *Dns6CacheEntry;
- DNS_RESOURCE_RECORD *Dns4RR;
- DNS6_RESOURCE_RECORD *Dns6RR;
- EFI_STATUS Status;
- UINT32 RemainingLength;
- EFI_TPL OldTpl;
- Item = NULL;
- Dns4TokenEntry = NULL;
- Dns6TokenEntry = NULL;
- IpCount = 0;
- RRCount = 0;
- AnswerSectionNum = 0;
- CNameTtl = 0;
- HostAddr4 = NULL;
- HostAddr6 = NULL;
- Dns4CacheEntry = NULL;
- Dns6CacheEntry = NULL;
- Dns4RR = NULL;
- Dns6RR = NULL;
- *Completed = TRUE;
- Status = EFI_SUCCESS;
- RemainingLength = Length;
- //
- // Check whether the remaining packet length is avaiable or not.
- //
- if (RemainingLength <= sizeof (DNS_HEADER)) {
- *Completed = FALSE;
- return EFI_ABORTED;
- } else {
- RemainingLength -= sizeof (DNS_HEADER);
- }
- //
- // Get header
- //
- DnsHeader = (DNS_HEADER *) RxString;
- DnsHeader->Identification = NTOHS (DnsHeader->Identification);
- DnsHeader->Flags.Uint16 = NTOHS (DnsHeader->Flags.Uint16);
- DnsHeader->QuestionsNum = NTOHS (DnsHeader->QuestionsNum);
- DnsHeader->AnswersNum = NTOHS (DnsHeader->AnswersNum);
- DnsHeader->AuthorityNum = NTOHS (DnsHeader->AuthorityNum);
- DnsHeader->AditionalNum = NTOHS (DnsHeader->AditionalNum);
- //
- // There is always one QuestionsNum in DNS message. The capability to handle more
- // than one requires to redesign the message format. Currently, it's not supported.
- //
- if (DnsHeader->QuestionsNum > 1) {
- *Completed = FALSE;
- return EFI_UNSUPPORTED;
- }
- //
- // Get Query name
- //
- QueryName = (CHAR8 *) (RxString + sizeof (*DnsHeader));
- QueryNameLen = (UINT32) AsciiStrLen (QueryName) + 1;
- //
- // Check whether the remaining packet length is avaiable or not.
- //
- if (RemainingLength <= QueryNameLen + sizeof (DNS_QUERY_SECTION)) {
- *Completed = FALSE;
- return EFI_ABORTED;
- } else {
- RemainingLength -= (QueryNameLen + sizeof (DNS_QUERY_SECTION));
- }
- //
- // Get query section
- //
- QuerySection = (DNS_QUERY_SECTION *) (QueryName + QueryNameLen);
- QuerySection->Type = NTOHS (QuerySection->Type);
- QuerySection->Class = NTOHS (QuerySection->Class);
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- //
- // Check DnsResponse Validity, if so, also get a valid NET_MAP_ITEM.
- //
- if (Instance->Service->IpVersion == IP_VERSION_4) {
- if (!IsValidDnsResponse (
- &Instance->Dns4TxTokens,
- DnsHeader->Identification,
- QuerySection->Type,
- QuerySection->Class,
- &Item
- )) {
- *Completed = FALSE;
- Status = EFI_ABORTED;
- goto ON_EXIT;
- }
- ASSERT (Item != NULL);
- Dns4TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);
- } else {
- if (!IsValidDnsResponse (
- &Instance->Dns6TxTokens,
- DnsHeader->Identification,
- QuerySection->Type,
- QuerySection->Class,
- &Item
- )) {
- *Completed = FALSE;
- Status = EFI_ABORTED;
- goto ON_EXIT;
- }
- ASSERT (Item != NULL);
- Dns6TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);
- }
- //
- // Continue Check Some Errors.
- //
- if (DnsHeader->Flags.Bits.RCode != DNS_FLAGS_RCODE_NO_ERROR || DnsHeader->AnswersNum < 1 || \
- DnsHeader->Flags.Bits.QR != DNS_FLAGS_QR_RESPONSE) {
- //
- // The domain name referenced in the query does not exist.
- //
- if (DnsHeader->Flags.Bits.RCode == DNS_FLAGS_RCODE_NAME_ERROR) {
- Status = EFI_NOT_FOUND;
- } else {
- Status = EFI_DEVICE_ERROR;
- }
- goto ON_COMPLETE;
- }
- //
- // Do some buffer allocations.
- //
- if (Instance->Service->IpVersion == IP_VERSION_4) {
- ASSERT (Dns4TokenEntry != NULL);
- if (Dns4TokenEntry->GeneralLookUp) {
- //
- // It's the GeneralLookUp querying.
- //
- Dns4TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));
- if (Dns4TokenEntry->Token->RspData.GLookupData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- Dns4TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));
- if (Dns4TokenEntry->Token->RspData.GLookupData->RRList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- } else {
- //
- // It's not the GeneralLookUp querying. Check the Query type.
- //
- if (QuerySection->Type == DNS_TYPE_A) {
- Dns4TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS_HOST_TO_ADDR_DATA));
- if (Dns4TokenEntry->Token->RspData.H2AData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));
- if (Dns4TokenEntry->Token->RspData.H2AData->IpList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- } else {
- Status = EFI_UNSUPPORTED;
- goto ON_EXIT;
- }
- }
- } else {
- ASSERT (Dns6TokenEntry != NULL);
- if (Dns6TokenEntry->GeneralLookUp) {
- //
- // It's the GeneralLookUp querying.
- //
- Dns6TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));
- if (Dns6TokenEntry->Token->RspData.GLookupData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- Dns6TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));
- if (Dns6TokenEntry->Token->RspData.GLookupData->RRList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- } else {
- //
- // It's not the GeneralLookUp querying. Check the Query type.
- //
- if (QuerySection->Type == DNS_TYPE_AAAA) {
- Dns6TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS6_HOST_TO_ADDR_DATA));
- if (Dns6TokenEntry->Token->RspData.H2AData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));
- if (Dns6TokenEntry->Token->RspData.H2AData->IpList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- } else {
- Status = EFI_UNSUPPORTED;
- goto ON_EXIT;
- }
- }
- }
- Status = EFI_NOT_FOUND;
- //
- // Get Answer name
- //
- AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection);
- //
- // Processing AnswerSection.
- //
- while (AnswerSectionNum < DnsHeader->AnswersNum) {
- //
- // Check whether the remaining packet length is avaiable or not.
- //
- if (RemainingLength <= sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION)) {
- *Completed = FALSE;
- Status = EFI_ABORTED;
- goto ON_EXIT;
- } else {
- RemainingLength -= (sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION));
- }
- //
- // Answer name should be PTR, else EFI_UNSUPPORTED returned.
- //
- if ((*(UINT8 *) AnswerName & 0xC0) != 0xC0) {
- Status = EFI_UNSUPPORTED;
- goto ON_EXIT;
- }
- //
- // Get Answer section.
- //
- AnswerSection = (DNS_ANSWER_SECTION *) (AnswerName + sizeof (UINT16));
- AnswerSection->Type = NTOHS (AnswerSection->Type);
- AnswerSection->Class = NTOHS (AnswerSection->Class);
- AnswerSection->Ttl = NTOHL (AnswerSection->Ttl);
- AnswerSection->DataLength = NTOHS (AnswerSection->DataLength);
- //
- // Check whether the remaining packet length is avaiable or not.
- //
- if (RemainingLength < AnswerSection->DataLength) {
- *Completed = FALSE;
- Status = EFI_ABORTED;
- goto ON_EXIT;
- } else {
- RemainingLength -= AnswerSection->DataLength;
- }
- //
- // Check whether it's the GeneralLookUp querying.
- //
- if (Instance->Service->IpVersion == IP_VERSION_4 && Dns4TokenEntry->GeneralLookUp) {
- Dns4RR = Dns4TokenEntry->Token->RspData.GLookupData->RRList;
- AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
- //
- // Fill the ResourceRecord.
- //
- Dns4RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);
- if (Dns4RR[RRCount].QName == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- CopyMem (Dns4RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));
- Dns4RR[RRCount].QType = AnswerSection->Type;
- Dns4RR[RRCount].QClass = AnswerSection->Class;
- Dns4RR[RRCount].TTL = AnswerSection->Ttl;
- Dns4RR[RRCount].DataLength = AnswerSection->DataLength;
- Dns4RR[RRCount].RData = AllocateZeroPool (Dns4RR[RRCount].DataLength);
- if (Dns4RR[RRCount].RData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- CopyMem (Dns4RR[RRCount].RData, AnswerData, Dns4RR[RRCount].DataLength);
- RRCount ++;
- Status = EFI_SUCCESS;
- } else if (Instance->Service->IpVersion == IP_VERSION_6 && Dns6TokenEntry->GeneralLookUp) {
- Dns6RR = Dns6TokenEntry->Token->RspData.GLookupData->RRList;
- AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
- //
- // Fill the ResourceRecord.
- //
- Dns6RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);
- if (Dns6RR[RRCount].QName == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- CopyMem (Dns6RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));
- Dns6RR[RRCount].QType = AnswerSection->Type;
- Dns6RR[RRCount].QClass = AnswerSection->Class;
- Dns6RR[RRCount].TTL = AnswerSection->Ttl;
- Dns6RR[RRCount].DataLength = AnswerSection->DataLength;
- Dns6RR[RRCount].RData = AllocateZeroPool (Dns6RR[RRCount].DataLength);
- if (Dns6RR[RRCount].RData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- CopyMem (Dns6RR[RRCount].RData, AnswerData, Dns6RR[RRCount].DataLength);
- RRCount ++;
- Status = EFI_SUCCESS;
- } else {
- //
- // It's not the GeneralLookUp querying.
- // Check the Query type, parse the response packet.
- //
- switch (AnswerSection->Type) {
- case DNS_TYPE_A:
- //
- // This is address entry, get Data.
- //
- ASSERT (Dns4TokenEntry != NULL);
- if (AnswerSection->DataLength != 4) {
- Status = EFI_ABORTED;
- goto ON_EXIT;
- }
- HostAddr4 = Dns4TokenEntry->Token->RspData.H2AData->IpList;
- AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
- CopyMem (&HostAddr4[IpCount], AnswerData, sizeof (EFI_IPv4_ADDRESS));
- //
- // Allocate new CacheEntry pool to update DNS cache dynamically.
- //
- Dns4CacheEntry = AllocateZeroPool (sizeof (EFI_DNS4_CACHE_ENTRY));
- if (Dns4CacheEntry == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- Dns4CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));
- if (Dns4CacheEntry->HostName == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- CopyMem (Dns4CacheEntry->HostName, Dns4TokenEntry->QueryHostName, 2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));
- Dns4CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));
- if (Dns4CacheEntry->IpAddress == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- CopyMem (Dns4CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv4_ADDRESS));
- if (CNameTtl != 0 && AnswerSection->Ttl != 0) {
- Dns4CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);
- } else {
- Dns4CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);
- }
- UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);
- //
- // Free allocated CacheEntry pool.
- //
- FreePool (Dns4CacheEntry->HostName);
- Dns4CacheEntry->HostName = NULL;
- FreePool (Dns4CacheEntry->IpAddress);
- Dns4CacheEntry->IpAddress = NULL;
- FreePool (Dns4CacheEntry);
- Dns4CacheEntry = NULL;
- IpCount ++;
- Status = EFI_SUCCESS;
- break;
- case DNS_TYPE_AAAA:
- //
- // This is address entry, get Data.
- //
- ASSERT (Dns6TokenEntry != NULL);
- if (AnswerSection->DataLength != 16) {
- Status = EFI_ABORTED;
- goto ON_EXIT;
- }
- HostAddr6 = Dns6TokenEntry->Token->RspData.H2AData->IpList;
- AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
- CopyMem (&HostAddr6[IpCount], AnswerData, sizeof (EFI_IPv6_ADDRESS));
- //
- // Allocate new CacheEntry pool to update DNS cache dynamically.
- //
- Dns6CacheEntry = AllocateZeroPool (sizeof (EFI_DNS6_CACHE_ENTRY));
- if (Dns6CacheEntry == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- Dns6CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));
- if (Dns6CacheEntry->HostName == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- CopyMem (Dns6CacheEntry->HostName, Dns6TokenEntry->QueryHostName, 2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));
- Dns6CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));
- if (Dns6CacheEntry->IpAddress == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
- CopyMem (Dns6CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv6_ADDRESS));
- if (CNameTtl != 0 && AnswerSection->Ttl != 0) {
- Dns6CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);
- } else {
- Dns6CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);
- }
- UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);
- //
- // Free allocated CacheEntry pool.
- //
- FreePool (Dns6CacheEntry->HostName);
- Dns6CacheEntry->HostName = NULL;
- FreePool (Dns6CacheEntry->IpAddress);
- Dns6CacheEntry->IpAddress = NULL;
- FreePool (Dns6CacheEntry);
- Dns6CacheEntry = NULL;
- IpCount ++;
- Status = EFI_SUCCESS;
- break;
- case DNS_TYPE_CNAME:
- //
- // According RFC 1034 - 3.6.2, if the query name is an alias, the name server will include the CNAME
- // record in the response and restart the query at the domain name specified in the data field of the
- // CNAME record. So, just record the TTL value of the CNAME, then skip to parse the next record.
- //
- CNameTtl = AnswerSection->Ttl;
- break;
- default:
- Status = EFI_UNSUPPORTED;
- goto ON_EXIT;
- }
- }
- //
- // Find next one
- //
- AnswerName = (CHAR8 *) AnswerSection + sizeof (*AnswerSection) + AnswerSection->DataLength;
- AnswerSectionNum ++;
- }
- if (Instance->Service->IpVersion == IP_VERSION_4) {
- ASSERT (Dns4TokenEntry != NULL);
- if (Dns4TokenEntry->GeneralLookUp) {
- Dns4TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;
- } else {
- if (QuerySection->Type == DNS_TYPE_A) {
- Dns4TokenEntry->Token->RspData.H2AData->IpCount = IpCount;
- } else {
- Status = EFI_UNSUPPORTED;
- goto ON_EXIT;
- }
- }
- } else {
- ASSERT (Dns6TokenEntry != NULL);
- if (Dns6TokenEntry->GeneralLookUp) {
- Dns6TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;
- } else {
- if (QuerySection->Type == DNS_TYPE_AAAA) {
- Dns6TokenEntry->Token->RspData.H2AData->IpCount = IpCount;
- } else {
- Status = EFI_UNSUPPORTED;
- goto ON_EXIT;
- }
- }
- }
- ON_COMPLETE:
- //
- // Parsing is complete, free the sending packet and signal Event here.
- //
- if (Item != NULL && Item->Value != NULL) {
- NetbufFree ((NET_BUF *) (Item->Value));
- }
- if (Instance->Service->IpVersion == IP_VERSION_4) {
- ASSERT (Dns4TokenEntry != NULL);
- Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);
- Dns4TokenEntry->Token->Status = Status;
- if (Dns4TokenEntry->Token->Event != NULL) {
- gBS->SignalEvent (Dns4TokenEntry->Token->Event);
- DispatchDpc ();
- }
- } else {
- ASSERT (Dns6TokenEntry != NULL);
- Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);
- Dns6TokenEntry->Token->Status = Status;
- if (Dns6TokenEntry->Token->Event != NULL) {
- gBS->SignalEvent (Dns6TokenEntry->Token->Event);
- DispatchDpc ();
- }
- }
- ON_EXIT:
- //
- // Free the allocated buffer if error happen.
- //
- if (EFI_ERROR (Status)) {
- if (Dns4TokenEntry != NULL) {
- if (Dns4TokenEntry->GeneralLookUp) {
- if (Dns4TokenEntry->Token->RspData.GLookupData != NULL) {
- if (Dns4TokenEntry->Token->RspData.GLookupData->RRList != NULL) {
- while (RRCount != 0) {
- RRCount --;
- if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {
- FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);
- }
- if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {
- FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);
- }
- }
- FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList);
- }
- FreePool (Dns4TokenEntry->Token->RspData.GLookupData);
- }
- } else {
- if (QuerySection->Type == DNS_TYPE_A && Dns4TokenEntry->Token->RspData.H2AData != NULL) {
- if (Dns4TokenEntry->Token->RspData.H2AData->IpList != NULL) {
- FreePool (Dns4TokenEntry->Token->RspData.H2AData->IpList);
- }
- FreePool (Dns4TokenEntry->Token->RspData.H2AData);
- }
- }
- }
- if (Dns6TokenEntry != NULL) {
- if (Dns6TokenEntry->GeneralLookUp) {
- if (Dns6TokenEntry->Token->RspData.GLookupData != NULL) {
- if (Dns6TokenEntry->Token->RspData.GLookupData->RRList != NULL) {
- while (RRCount != 0) {
- RRCount --;
- if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {
- FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);
- }
- if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {
- FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);
- }
- }
- FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList);
- }
- FreePool (Dns6TokenEntry->Token->RspData.GLookupData);
- }
- } else {
- if (QuerySection->Type == DNS_TYPE_AAAA && Dns6TokenEntry->Token->RspData.H2AData != NULL) {
- if (Dns6TokenEntry->Token->RspData.H2AData->IpList != NULL) {
- FreePool (Dns6TokenEntry->Token->RspData.H2AData->IpList);
- }
- FreePool (Dns6TokenEntry->Token->RspData.H2AData);
- }
- }
- }
- if (Dns4CacheEntry != NULL) {
- if (Dns4CacheEntry->HostName != NULL) {
- FreePool (Dns4CacheEntry->HostName);
- }
- if (Dns4CacheEntry->IpAddress != NULL) {
- FreePool (Dns4CacheEntry->IpAddress);
- }
- FreePool (Dns4CacheEntry);
- }
- if (Dns6CacheEntry != NULL) {
- if (Dns6CacheEntry->HostName != NULL) {
- FreePool (Dns6CacheEntry->HostName);
- }
- if (Dns6CacheEntry->IpAddress != NULL) {
- FreePool (Dns6CacheEntry->IpAddress);
- }
- FreePool (Dns6CacheEntry);
- }
- }
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- Parse response packet.
- @param Packet The packets received.
- @param EndPoint The local/remote UDP access point
- @param IoStatus The status of the UDP receive
- @param Context The opaque parameter to the function.
- **/
- VOID
- EFIAPI
- DnsOnPacketReceived (
- NET_BUF *Packet,
- UDP_END_POINT *EndPoint,
- EFI_STATUS IoStatus,
- VOID *Context
- )
- {
- DNS_INSTANCE *Instance;
- UINT8 *RcvString;
- UINT32 Len;
- BOOLEAN Completed;
- Instance = (DNS_INSTANCE *) Context;
- NET_CHECK_SIGNATURE (Instance, DNS_INSTANCE_SIGNATURE);
- RcvString = NULL;
- Completed = FALSE;
- if (EFI_ERROR (IoStatus)) {
- goto ON_EXIT;
- }
- ASSERT (Packet != NULL);
- Len = Packet->TotalSize;
- RcvString = NetbufGetByte (Packet, 0, NULL);
- ASSERT (RcvString != NULL);
- //
- // Parse Dns Response
- //
- ParseDnsResponse (Instance, RcvString, Len, &Completed);
- ON_EXIT:
- if (Packet != NULL) {
- NetbufFree (Packet);
- }
- if (!Completed) {
- UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);
- }
- }
- /**
- Release the net buffer when packet is sent.
- @param Packet The packets received.
- @param EndPoint The local/remote UDP access point
- @param IoStatus The status of the UDP receive
- @param Context The opaque parameter to the function.
- **/
- VOID
- EFIAPI
- DnsOnPacketSent (
- NET_BUF *Packet,
- UDP_END_POINT *EndPoint,
- EFI_STATUS IoStatus,
- VOID *Context
- )
- {
- DNS_INSTANCE *Instance;
- LIST_ENTRY *Entry;
- NET_MAP_ITEM *Item;
- DNS4_TOKEN_ENTRY *Dns4TokenEntry;
- DNS6_TOKEN_ENTRY *Dns6TokenEntry;
- Dns4TokenEntry = NULL;
- Dns6TokenEntry = NULL;
- Instance = (DNS_INSTANCE *) Context;
- NET_CHECK_SIGNATURE (Instance, DNS_INSTANCE_SIGNATURE);
- if (Instance->Service->IpVersion == IP_VERSION_4) {
- NET_LIST_FOR_EACH (Entry, &Instance->Dns4TxTokens.Used) {
- Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
- if (Packet == (NET_BUF *)(Item->Value)) {
- Dns4TokenEntry = ((DNS4_TOKEN_ENTRY *)Item->Key);
- Dns4TokenEntry->PacketToLive = Dns4TokenEntry->Token->RetryInterval;
- break;
- }
- }
- } else {
- NET_LIST_FOR_EACH (Entry, &Instance->Dns6TxTokens.Used) {
- Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
- if (Packet == (NET_BUF *)(Item->Value)) {
- Dns6TokenEntry = ((DNS6_TOKEN_ENTRY *)Item->Key);
- Dns6TokenEntry->PacketToLive = Dns6TokenEntry->Token->RetryInterval;
- break;
- }
- }
- }
- NetbufFree (Packet);
- }
- /**
- Query request information.
- @param Instance The DNS instance
- @param Packet The packet for querying request information.
- @retval EFI_SUCCESS Query request information successfully.
- @retval Others Failed to query request information.
- **/
- EFI_STATUS
- DoDnsQuery (
- IN DNS_INSTANCE *Instance,
- IN NET_BUF *Packet
- )
- {
- EFI_STATUS Status;
- //
- // Ready to receive the DNS response.
- //
- if (Instance->UdpIo->RecvRequest == NULL) {
- Status = UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
- //
- // Transmit the DNS packet.
- //
- NET_GET_REF (Packet);
- Status = UdpIoSendDatagram (Instance->UdpIo, Packet, NULL, NULL, DnsOnPacketSent, Instance);
- return Status;
- }
- /**
- Construct the Packet according query section.
- @param Instance The DNS instance
- @param QueryName Queried Name
- @param Type Queried Type
- @param Class Queried Class
- @param Packet The packet for query
- @retval EFI_SUCCESS The packet is constructed.
- @retval Others Failed to construct the Packet.
- **/
- EFI_STATUS
- ConstructDNSQuery (
- IN DNS_INSTANCE *Instance,
- IN CHAR8 *QueryName,
- IN UINT16 Type,
- IN UINT16 Class,
- OUT NET_BUF **Packet
- )
- {
- NET_FRAGMENT Frag;
- DNS_HEADER *DnsHeader;
- DNS_QUERY_SECTION *DnsQuery;
- //
- // Messages carried by UDP are restricted to 512 bytes (not counting the IP
- // or UDP headers).
- //
- Frag.Bulk = AllocatePool (DNS_MAX_MESSAGE_SIZE * sizeof (UINT8));
- if (Frag.Bulk == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Fill header
- //
- DnsHeader = (DNS_HEADER *) Frag.Bulk;
- DnsHeader->Identification = (UINT16)NET_RANDOM (NetRandomInitSeed());
- DnsHeader->Flags.Uint16 = 0x0000;
- DnsHeader->Flags.Bits.RD = 1;
- DnsHeader->Flags.Bits.OpCode = DNS_FLAGS_OPCODE_STANDARD;
- DnsHeader->Flags.Bits.QR = DNS_FLAGS_QR_QUERY;
- DnsHeader->QuestionsNum = 1;
- DnsHeader->AnswersNum = 0;
- DnsHeader->AuthorityNum = 0;
- DnsHeader->AditionalNum = 0;
- DnsHeader->Identification = HTONS (DnsHeader->Identification);
- DnsHeader->Flags.Uint16 = HTONS (DnsHeader->Flags.Uint16);
- DnsHeader->QuestionsNum = HTONS (DnsHeader->QuestionsNum);
- DnsHeader->AnswersNum = HTONS (DnsHeader->AnswersNum);
- DnsHeader->AuthorityNum = HTONS (DnsHeader->AuthorityNum);
- DnsHeader->AditionalNum = HTONS (DnsHeader->AditionalNum);
- Frag.Len = sizeof (*DnsHeader);
- //
- // Fill Query name
- //
- CopyMem (Frag.Bulk + Frag.Len, QueryName, AsciiStrLen (QueryName));
- Frag.Len = (UINT32) (Frag.Len + AsciiStrLen (QueryName));
- *(Frag.Bulk + Frag.Len) = 0;
- Frag.Len ++;
- //
- // Rest query section
- //
- DnsQuery = (DNS_QUERY_SECTION *) (Frag.Bulk + Frag.Len);
- DnsQuery->Type = HTONS (Type);
- DnsQuery->Class = HTONS (Class);
- Frag.Len += sizeof (*DnsQuery);
- //
- // Wrap the Frag in a net buffer.
- //
- *Packet = NetbufFromExt (&Frag, 1, 0, 0, DnsDummyExtFree, NULL);
- if (*Packet == NULL) {
- FreePool (Frag.Bulk);
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Store the UdpIo in ProtoData.
- //
- *((UINTN *) &((*Packet)->ProtoData[0])) = (UINTN) (Instance->UdpIo);
- return EFI_SUCCESS;
- }
- /**
- Retransmit the packet.
- @param Instance The DNS instance
- @param Packet Retransmit the packet
- @retval EFI_SUCCESS The packet is retransmitted.
- @retval Others Failed to retransmit.
- **/
- EFI_STATUS
- DnsRetransmit (
- IN DNS_INSTANCE *Instance,
- IN NET_BUF *Packet
- )
- {
- EFI_STATUS Status;
- UINT8 *Buffer;
- ASSERT (Packet != NULL);
- //
- // Set the requests to the listening port, other packets to the connected port
- //
- Buffer = NetbufGetByte (Packet, 0, NULL);
- ASSERT (Buffer != NULL);
- NET_GET_REF (Packet);
- Status = UdpIoSendDatagram (
- Instance->UdpIo,
- Packet,
- NULL,
- NULL,
- DnsOnPacketSent,
- Instance
- );
- if (EFI_ERROR (Status)) {
- NET_PUT_REF (Packet);
- }
- return Status;
- }
- /**
- The timer ticking function for the DNS services.
- @param Event The ticking event
- @param Context The DNS service instance
- **/
- VOID
- EFIAPI
- DnsOnTimerRetransmit (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- DNS_SERVICE *Service;
- LIST_ENTRY *Entry;
- LIST_ENTRY *Next;
- DNS_INSTANCE *Instance;
- LIST_ENTRY *EntryNetMap;
- NET_MAP_ITEM *ItemNetMap;
- DNS4_TOKEN_ENTRY *Dns4TokenEntry;
- DNS6_TOKEN_ENTRY *Dns6TokenEntry;
- Dns4TokenEntry = NULL;
- Dns6TokenEntry = NULL;
- Service = (DNS_SERVICE *) Context;
- if (Service->IpVersion == IP_VERSION_4) {
- //
- // Iterate through all the children of the DNS service instance. Time
- // out the packet. If maximum retries reached, clean the Token up.
- //
- NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Dns4ChildrenList) {
- Instance = NET_LIST_USER_STRUCT (Entry, DNS_INSTANCE, Link);
- EntryNetMap = Instance->Dns4TxTokens.Used.ForwardLink;
- while (EntryNetMap != &Instance->Dns4TxTokens.Used) {
- ItemNetMap = NET_LIST_USER_STRUCT (EntryNetMap, NET_MAP_ITEM, Link);
- Dns4TokenEntry = (DNS4_TOKEN_ENTRY *)(ItemNetMap->Key);
- if (Dns4TokenEntry->PacketToLive == 0 || (--Dns4TokenEntry->PacketToLive > 0)) {
- EntryNetMap = EntryNetMap->ForwardLink;
- continue;
- }
- //
- // Retransmit the packet if haven't reach the maxmium retry count,
- // otherwise exit the transfer.
- //
- if (++Dns4TokenEntry->RetryCounting <= Dns4TokenEntry->Token->RetryCount) {
- DnsRetransmit (Instance, (NET_BUF *)ItemNetMap->Value);
- EntryNetMap = EntryNetMap->ForwardLink;
- } else {
- //
- // Maximum retries reached, clean the Token up.
- //
- Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);
- Dns4TokenEntry->Token->Status = EFI_TIMEOUT;
- gBS->SignalEvent (Dns4TokenEntry->Token->Event);
- DispatchDpc ();
- //
- // Free the sending packet.
- //
- if (ItemNetMap->Value != NULL) {
- NetbufFree ((NET_BUF *)(ItemNetMap->Value));
- }
- EntryNetMap = Instance->Dns4TxTokens.Used.ForwardLink;
- }
- }
- }
- }else {
- //
- // Iterate through all the children of the DNS service instance. Time
- // out the packet. If maximum retries reached, clean the Token up.
- //
- NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Dns6ChildrenList) {
- Instance = NET_LIST_USER_STRUCT (Entry, DNS_INSTANCE, Link);
- EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;
- while (EntryNetMap != &Instance->Dns6TxTokens.Used) {
- ItemNetMap = NET_LIST_USER_STRUCT (EntryNetMap, NET_MAP_ITEM, Link);
- Dns6TokenEntry = (DNS6_TOKEN_ENTRY *) (ItemNetMap->Key);
- if (Dns6TokenEntry->PacketToLive == 0 || (--Dns6TokenEntry->PacketToLive > 0)) {
- EntryNetMap = EntryNetMap->ForwardLink;
- continue;
- }
- //
- // Retransmit the packet if haven't reach the maxmium retry count,
- // otherwise exit the transfer.
- //
- if (++Dns6TokenEntry->RetryCounting <= Dns6TokenEntry->Token->RetryCount) {
- DnsRetransmit (Instance, (NET_BUF *) ItemNetMap->Value);
- EntryNetMap = EntryNetMap->ForwardLink;
- } else {
- //
- // Maximum retries reached, clean the Token up.
- //
- Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);
- Dns6TokenEntry->Token->Status = EFI_TIMEOUT;
- gBS->SignalEvent (Dns6TokenEntry->Token->Event);
- DispatchDpc ();
- //
- // Free the sending packet.
- //
- if (ItemNetMap->Value != NULL) {
- NetbufFree ((NET_BUF *) (ItemNetMap->Value));
- }
- EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;
- }
- }
- }
- }
- }
- /**
- The timer ticking function for the DNS driver.
- @param Event The ticking event
- @param Context NULL
- **/
- VOID
- EFIAPI
- DnsOnTimerUpdate (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- LIST_ENTRY *Entry;
- LIST_ENTRY *Next;
- DNS4_CACHE *Item4;
- DNS6_CACHE *Item6;
- Item4 = NULL;
- Item6 = NULL;
- //
- // Iterate through all the DNS4 cache list.
- //
- NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {
- Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
- Item4->DnsCache.Timeout--;
- }
- Entry = mDriverData->Dns4CacheList.ForwardLink;
- while (Entry != &mDriverData->Dns4CacheList) {
- Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
- if (Item4->DnsCache.Timeout == 0) {
- RemoveEntryList (&Item4->AllCacheLink);
- FreePool (Item4->DnsCache.HostName);
- FreePool (Item4->DnsCache.IpAddress);
- FreePool (Item4);
- Entry = mDriverData->Dns4CacheList.ForwardLink;
- } else {
- Entry = Entry->ForwardLink;
- }
- }
- //
- // Iterate through all the DNS6 cache list.
- //
- NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
- Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
- Item6->DnsCache.Timeout--;
- }
- Entry = mDriverData->Dns6CacheList.ForwardLink;
- while (Entry != &mDriverData->Dns6CacheList) {
- Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
- if (Item6->DnsCache.Timeout == 0) {
- RemoveEntryList (&Item6->AllCacheLink);
- FreePool (Item6->DnsCache.HostName);
- FreePool (Item6->DnsCache.IpAddress);
- FreePool (Item6);
- Entry = mDriverData->Dns6CacheList.ForwardLink;
- } else {
- Entry = Entry->ForwardLink;
- }
- }
- }
|