1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266 |
- /** @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 successfully.
- @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 successfully.
- @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 cancel 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 cancel 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 successfully.
- @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 successfully.
- @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 occurred.
- **/
- 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 occurred.
- **/
- 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 available 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 available 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 available 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 available 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);
- Dns4TokenEntry->Token->RspData.H2AData = NULL;
- }
- }
- }
- 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);
- Dns6TokenEntry->Token->RspData.H2AData = NULL;
- }
- }
- }
- 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 maximum 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 maximum 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;
- }
- }
- }
|