resolv.c 125 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773
  1. /* resolv.c: DNS Resolver
  2. *
  3. * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
  4. * The Silver Hammer Group, Ltd.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Library General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. */
  11. /*
  12. * Portions Copyright (c) 1985, 1993
  13. * The Regents of the University of California. All rights reserved.
  14. * Portions Copyright © 2021 mirabilos <m@mirbsd.org>
  15. *
  16. * Redistribution and use in source and binary forms, with or without
  17. * modification, are permitted provided that the following conditions
  18. * are met:
  19. * 1. Redistributions of source code must retain the above copyright
  20. * notice, this list of conditions and the following disclaimer.
  21. * 2. Redistributions in binary form must reproduce the above copyright
  22. * notice, this list of conditions and the following disclaimer in the
  23. * documentation and/or other materials provided with the distribution.
  24. * 4. Neither the name of the University nor the names of its contributors
  25. * may be used to endorse or promote products derived from this software
  26. * without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  29. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  32. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  37. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  38. * SUCH DAMAGE.
  39. */
  40. /*
  41. * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  42. *
  43. * Permission to use, copy, modify, and distribute this software for any
  44. * purpose with or without fee is hereby granted, provided that the above
  45. * copyright notice and this permission notice appear in all copies, and that
  46. * the name of Digital Equipment Corporation not be used in advertising or
  47. * publicity pertaining to distribution of the document or software without
  48. * specific, written prior permission.
  49. *
  50. * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  51. * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  52. * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
  53. * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  54. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  55. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  56. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  57. * SOFTWARE.
  58. */
  59. /*
  60. * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
  61. *
  62. * Permission to use, copy, modify, and distribute this software for any
  63. * purpose with or without fee is hereby granted, provided that the above
  64. * copyright notice and this permission notice appear in all copies.
  65. *
  66. * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
  67. * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
  68. * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
  69. * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  70. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  71. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  72. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  73. * SOFTWARE.
  74. */
  75. /* RFC 1035
  76. ...
  77. Whenever an octet represents a numeric quantity, the left most bit
  78. in the diagram is the high order or most significant bit.
  79. That is, the bit labeled 0 is the most significant bit.
  80. ...
  81. 4.1.1. Header section format
  82. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  83. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  84. | ID |
  85. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  86. |QR| OPCODE |AA|TC|RD|RA| 0 0 0| RCODE |
  87. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  88. | QDCOUNT |
  89. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  90. | ANCOUNT |
  91. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  92. | NSCOUNT |
  93. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  94. | ARCOUNT |
  95. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  96. ID 16 bit random identifier assigned by querying peer.
  97. Used to match query/response.
  98. QR message is a query (0), or a response (1).
  99. OPCODE 0 standard query (QUERY)
  100. 1 inverse query (IQUERY)
  101. 2 server status request (STATUS)
  102. AA Authoritative Answer - this bit is valid in responses.
  103. Responding name server is an authority for the domain name
  104. in question section. Answer section may have multiple owner names
  105. because of aliases. The AA bit corresponds to the name which matches
  106. the query name, or the first owner name in the answer section.
  107. TC TrunCation - this message was truncated.
  108. RD Recursion Desired - this bit may be set in a query and
  109. is copied into the response. If RD is set, it directs
  110. the name server to pursue the query recursively.
  111. Recursive query support is optional.
  112. RA Recursion Available - this be is set or cleared in a
  113. response, and denotes whether recursive query support is
  114. available in the name server.
  115. RCODE Response code.
  116. 0 No error condition
  117. 1 Format error
  118. 2 Server failure - server was unable to process the query
  119. due to a problem with the name server.
  120. 3 Name Error - meaningful only for responses from
  121. an authoritative name server. The referenced domain name
  122. does not exist.
  123. 4 Not Implemented.
  124. 5 Refused.
  125. QDCOUNT number of entries in the question section.
  126. ANCOUNT number of records in the answer section.
  127. NSCOUNT number of records in the authority records section.
  128. ARCOUNT number of records in the additional records section.
  129. 4.1.2. Question section format
  130. The section contains QDCOUNT (usually 1) entries, each of this format:
  131. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  132. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  133. / QNAME /
  134. / /
  135. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  136. | QTYPE |
  137. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  138. | QCLASS |
  139. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  140. QNAME a domain name represented as a sequence of labels, where
  141. each label consists of a length octet followed by that
  142. number of octets. The domain name terminates with the
  143. zero length octet for the null label of the root. Note
  144. that this field may be an odd number of octets; no
  145. padding is used.
  146. QTYPE a two octet type of the query.
  147. 1 a host address [REQ_A const]
  148. 2 an authoritative name server
  149. 3 a mail destination (Obsolete - use MX)
  150. 4 a mail forwarder (Obsolete - use MX)
  151. 5 the canonical name for an alias
  152. 6 marks the start of a zone of authority
  153. 7 a mailbox domain name (EXPERIMENTAL)
  154. 8 a mail group member (EXPERIMENTAL)
  155. 9 a mail rename domain name (EXPERIMENTAL)
  156. 10 a null RR (EXPERIMENTAL)
  157. 11 a well known service description
  158. 12 a domain name pointer [REQ_PTR const]
  159. 13 host information
  160. 14 mailbox or mail list information
  161. 15 mail exchange
  162. 16 text strings
  163. 0x1c IPv6?
  164. 252 a request for a transfer of an entire zone
  165. 253 a request for mailbox-related records (MB, MG or MR)
  166. 254 a request for mail agent RRs (Obsolete - see MX)
  167. 255 a request for all records
  168. QCLASS a two octet code that specifies the class of the query.
  169. 1 the Internet
  170. (others are historic only)
  171. 255 any class
  172. 4.1.3. Resource record format
  173. The answer, authority, and additional sections all share the same format:
  174. a variable number of resource records, where the number of records
  175. is specified in the corresponding count field in the header.
  176. Each resource record has this format:
  177. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  178. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  179. / /
  180. / NAME /
  181. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  182. | TYPE |
  183. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  184. | CLASS |
  185. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  186. | TTL |
  187. | |
  188. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  189. | RDLENGTH |
  190. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
  191. / RDATA /
  192. / /
  193. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  194. NAME a domain name to which this resource record pertains.
  195. TYPE two octets containing one of the RR type codes. This
  196. field specifies the meaning of the data in the RDATA field.
  197. CLASS two octets which specify the class of the data in the RDATA field.
  198. TTL a 32 bit unsigned integer that specifies the time interval
  199. (in seconds) that the record may be cached.
  200. RDLENGTH a 16 bit integer, length in octets of the RDATA field.
  201. RDATA a variable length string of octets that describes the resource.
  202. The format of this information varies according to the TYPE
  203. and CLASS of the resource record.
  204. If the TYPE is A and the CLASS is IN, it's a 4 octet IP address.
  205. 4.1.4. Message compression
  206. In order to reduce the size of messages, domain names can be compressed.
  207. An entire domain name or a list of labels at the end of a domain name
  208. is replaced with a pointer to a prior occurance of the same name.
  209. The pointer takes the form of a two octet sequence:
  210. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  211. | 1 1| OFFSET |
  212. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  213. The first two bits are ones. This allows a pointer to be distinguished
  214. from a label, since the label must begin with two zero bits because
  215. labels are restricted to 63 octets or less. The OFFSET field specifies
  216. an offset from the start of the message (i.e., the first octet
  217. of the ID field in the domain header).
  218. A zero offset specifies the first byte of the ID field, etc.
  219. Domain name in a message can be represented as either:
  220. - a sequence of labels ending in a zero octet
  221. - a pointer
  222. - a sequence of labels ending with a pointer
  223. */
  224. #include <string.h>
  225. #include <stdio.h>
  226. #include <stdio_ext.h>
  227. #include <signal.h>
  228. #include <malloc.h>
  229. #include <errno.h>
  230. #include <sys/poll.h>
  231. #include <sys/socket.h>
  232. #include <sys/types.h>
  233. #include <sys/time.h>
  234. #include <netinet/in.h>
  235. #include <arpa/inet.h>
  236. #include <stdlib.h>
  237. #include <unistd.h>
  238. #include <resolv.h>
  239. #include <netdb.h>
  240. #include <ctype.h>
  241. #include <stdbool.h>
  242. #include <stdint.h>
  243. #include <time.h>
  244. #include <arpa/nameser.h>
  245. #include <sys/utsname.h>
  246. #include <sys/un.h>
  247. #include <sys/stat.h>
  248. #include <sys/param.h>
  249. #include <bits/uClibc_mutex.h>
  250. #include <fcntl.h>
  251. #include "internal/parse_config.h"
  252. /* poll() is not supported in kernel <= 2.0, therefore if __NR_poll is
  253. * not available, we assume an old Linux kernel is in use and we will
  254. * use select() instead. */
  255. #include <sys/syscall.h>
  256. #ifndef __NR_poll
  257. # define USE_SELECT
  258. #endif
  259. #if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__
  260. #define IF_HAS_BOTH(...) __VA_ARGS__
  261. #else
  262. #define IF_HAS_BOTH(...)
  263. #endif
  264. #define MAX_RECURSE 5
  265. #define MAXALIASES (4)
  266. /* 1:ip + 1:full + MAX_ALIASES:aliases + 1:NULL */
  267. #define ALIAS_DIM (2 + MAXALIASES + 1)
  268. #define BUFSZ (80) /* one line */
  269. #define NS_TYPE_ELT 0x40 /*%< EDNS0 extended label type */
  270. #define DNS_LABELTYPE_BITSTRING 0x41
  271. #undef DEBUG
  272. /* #define DEBUG */
  273. #ifdef DEBUG
  274. #define DPRINTF(X,args...) fprintf(stderr, X, ##args)
  275. #else
  276. #define DPRINTF(X,args...)
  277. #endif
  278. /* Make sure the incoming char * buffer is aligned enough to handle our random
  279. * structures. This define is the same as we use for malloc alignment (which
  280. * has same requirements). The offset is the number of bytes we need to adjust
  281. * in order to attain desired alignment.
  282. */
  283. #define ALIGN_ATTR __alignof__(double __attribute_aligned__ (sizeof(size_t)))
  284. #define ALIGN_BUFFER_OFFSET(buf) ((ALIGN_ATTR - ((size_t)buf % ALIGN_ATTR)) % ALIGN_ATTR)
  285. /* Structs */
  286. struct resolv_header {
  287. int id;
  288. int qr, opcode, aa, tc, rd, ra, rcode;
  289. int qdcount;
  290. int ancount;
  291. int nscount;
  292. int arcount;
  293. };
  294. struct resolv_question {
  295. char *dotted;
  296. int qtype;
  297. int qclass;
  298. };
  299. struct resolv_answer {
  300. char *dotted;
  301. int atype;
  302. int aclass;
  303. int ttl;
  304. int rdlength;
  305. const unsigned char *rdata;
  306. int rdoffset;
  307. char* buf;
  308. size_t buflen;
  309. size_t add_count;
  310. };
  311. enum etc_hosts_action {
  312. GET_HOSTS_BYNAME = 0,
  313. GETHOSTENT,
  314. GET_HOSTS_BYADDR,
  315. };
  316. typedef union sockaddr46_t {
  317. struct sockaddr sa;
  318. #ifdef __UCLIBC_HAS_IPV4__
  319. struct sockaddr_in sa4;
  320. #endif
  321. #ifdef __UCLIBC_HAS_IPV6__
  322. struct sockaddr_in6 sa6;
  323. #endif
  324. } sockaddr46_t;
  325. __UCLIBC_MUTEX_EXTERN(__resolv_lock) attribute_hidden;
  326. /* Protected by __resolv_lock */
  327. extern void (*__res_sync)(void) attribute_hidden;
  328. /*extern uint32_t __resolv_opts attribute_hidden; */
  329. extern uint8_t __resolv_timeout attribute_hidden;
  330. extern uint8_t __resolv_attempts attribute_hidden;
  331. extern unsigned __nameservers attribute_hidden;
  332. extern unsigned __searchdomains attribute_hidden;
  333. extern sockaddr46_t *__nameserver attribute_hidden;
  334. extern char **__searchdomain attribute_hidden;
  335. #ifdef __UCLIBC_HAS_IPV4__
  336. extern const struct sockaddr_in __local_nameserver attribute_hidden;
  337. #else
  338. extern const struct sockaddr_in6 __local_nameserver attribute_hidden;
  339. #endif
  340. /* Arbitrary */
  341. #define MAXLEN_searchdomain 128
  342. /* prototypes for internal functions */
  343. extern void endhostent_unlocked(void) attribute_hidden;
  344. extern int __get_hosts_byname_r(const char *name,
  345. int type,
  346. struct hostent *result_buf,
  347. char *buf,
  348. size_t buflen,
  349. struct hostent **result,
  350. int *h_errnop) attribute_hidden;
  351. extern int __get_hosts_byaddr_r(const char *addr,
  352. int len,
  353. int type,
  354. struct hostent *result_buf,
  355. char *buf,
  356. size_t buflen,
  357. struct hostent **result,
  358. int *h_errnop) attribute_hidden;
  359. extern parser_t *__open_etc_hosts(void) attribute_hidden;
  360. extern int __read_etc_hosts_r(parser_t *parser,
  361. const char *name,
  362. int type,
  363. enum etc_hosts_action action,
  364. struct hostent *result_buf,
  365. char *buf,
  366. size_t buflen,
  367. struct hostent **result,
  368. int *h_errnop) attribute_hidden;
  369. extern int __dns_lookup(const char *name,
  370. int type,
  371. unsigned char **outpacket,
  372. struct resolv_answer *a) attribute_hidden;
  373. extern int __encode_header(struct resolv_header *h,
  374. unsigned char *dest,
  375. int maxlen) attribute_hidden;
  376. extern void __decode_header(unsigned char *data,
  377. struct resolv_header *h) attribute_hidden;
  378. extern int __encode_question(const struct resolv_question *q,
  379. unsigned char *dest,
  380. int maxlen) attribute_hidden;
  381. extern int __encode_answer(struct resolv_answer *a,
  382. unsigned char *dest,
  383. int maxlen) attribute_hidden;
  384. extern void __open_nameservers(void) attribute_hidden;
  385. extern void __close_nameservers(void) attribute_hidden;
  386. extern int __hnbad(const char *dotted) attribute_hidden;
  387. #define __encode_dotted(dotted,dest,maxlen) \
  388. dn_comp((dotted), (dest), (maxlen), NULL, NULL)
  389. #define __decode_dotted(packet,offset,packet_len,dest,dest_len) \
  390. dn_expand((packet), (packet) + (packet_len), (packet) + (offset), \
  391. (dest), (dest_len))
  392. /*
  393. * Theory of operation.
  394. *
  395. * gethostbyname, getaddrinfo and friends end up here, and they sometimes
  396. * need to talk to DNS servers. In order to do this, we need to read /etc/resolv.conf
  397. * and determine servers' addresses and the like. resolv.conf format:
  398. *
  399. * nameserver <IP[v6]>
  400. * Address of DNS server. Cumulative.
  401. * If not specified, assumed to be on localhost.
  402. * search <domain1>[ <domain2>]...
  403. * Append these domains to unqualified names.
  404. * See ndots:n option.
  405. * $LOCALDOMAIN (space-separated list) overrides this.
  406. * domain <domain>
  407. * Effectively same as "search" with one domain.
  408. * If no "domain" line is present, the domain is determined
  409. * from the local host name returned by gethostname();
  410. * the domain part is taken to be everything after the first dot.
  411. * If there are no dots, there will be no "domain".
  412. * The domain and search keywords are mutually exclusive.
  413. * If more than one instance of these keywords is present,
  414. * the last instance wins.
  415. * sortlist 130.155.160.0[/255.255.240.0] 130.155.0.0
  416. * Allows addresses returned by gethostbyname to be sorted.
  417. * Not supported.
  418. * options option[ option]...
  419. * (so far we support timeout:n and attempts:n)
  420. * $RES_OPTIONS (space-separated list) is to be added to "options"
  421. * debug sets RES_DEBUG in _res.options
  422. * ndots:n how many dots there should be so that name will be tried
  423. * first as an absolute name before any search list elements
  424. * are appended to it. Default 1
  425. * timeout:n how long to wait for response. Default 5
  426. * (sun seems to have retrans:n synonym)
  427. * attempts:n number of rounds to do before giving up and returning
  428. * an error. Default 2
  429. * (sun seems to have retry:n synonym)
  430. * rotate sets RES_ROTATE in _res.options, round robin
  431. * selection of nameservers. Otherwise try
  432. * the first listed server first every time
  433. * no-check-names
  434. * sets RES_NOCHECKNAME in _res.options, which disables
  435. * checking of incoming host names for invalid characters
  436. * such as underscore (_), non-ASCII, or control characters
  437. * inet6 sets RES_USE_INET6 in _res.options. Try a AAAA query
  438. * before an A query inside the gethostbyname(), and map
  439. * IPv4 responses in IPv6 "tunnelled form" if no AAAA records
  440. * are found but an A record set exists
  441. * no_tld_query (FreeBSDism?)
  442. * do not attempt to resolve names without dots
  443. *
  444. * We will read and analyze /etc/resolv.conf as needed before
  445. * we do a DNS request. This happens in __dns_lookup.
  446. * It is reread if its mtime is changed.
  447. *
  448. * BSD has res_init routine which is used to initialize resolver state
  449. * which is held in global structure _res.
  450. * Generally, programs call res_init, then fiddle with _res.XXX
  451. * (_res.options and _res.nscount, _res.nsaddr_list[N]
  452. * are popular targets of fiddling) and expect subsequent calls
  453. * to gethostbyname, getaddrinfo, etc to use modified information.
  454. *
  455. * However, historical _res structure is quite awkward.
  456. * Using it for storing /etc/resolv.conf info is not desirable,
  457. * and __dns_lookup does not use it.
  458. *
  459. * We would like to avoid using it unless absolutely necessary.
  460. * If user doesn't use res_init, we should arrange it so that
  461. * _res structure doesn't even *get linked in* into user's application
  462. * (imagine static uclibc build here).
  463. *
  464. * The solution is a __res_sync function pointer, which is normally NULL.
  465. * But if res_init is called, it gets set and any subsequent gethostbyname
  466. * et al "syncronizes" our internal structures with potentially
  467. * modified _res.XXX stuff by calling __res_sync.
  468. * The trick here is that if res_init is not used and not linked in,
  469. * gethostbyname itself won't reference _res and _res won't be linked in
  470. * either. Other possible methods like
  471. * if (__res_sync_just_an_int_flag)
  472. * __sync_me_with_res()
  473. * would pull in __sync_me_with_res, which pulls in _res. Bad.
  474. */
  475. #ifdef L_encodeh
  476. int __encode_header(struct resolv_header *h, unsigned char *dest, int maxlen)
  477. {
  478. if (maxlen < HFIXEDSZ)
  479. return -1;
  480. dest[0] = (h->id & 0xff00) >> 8;
  481. dest[1] = (h->id & 0x00ff) >> 0;
  482. dest[2] = (h->qr ? 0x80 : 0) |
  483. ((h->opcode & 0x0f) << 3) |
  484. (h->aa ? 0x04 : 0) |
  485. (h->tc ? 0x02 : 0) |
  486. (h->rd ? 0x01 : 0);
  487. dest[3] = (h->ra ? 0x80 : 0) | (h->rcode & 0x0f);
  488. dest[4] = (h->qdcount & 0xff00) >> 8;
  489. dest[5] = (h->qdcount & 0x00ff) >> 0;
  490. dest[6] = (h->ancount & 0xff00) >> 8;
  491. dest[7] = (h->ancount & 0x00ff) >> 0;
  492. dest[8] = (h->nscount & 0xff00) >> 8;
  493. dest[9] = (h->nscount & 0x00ff) >> 0;
  494. dest[10] = (h->arcount & 0xff00) >> 8;
  495. dest[11] = (h->arcount & 0x00ff) >> 0;
  496. return HFIXEDSZ;
  497. }
  498. #endif /* L_encodeh */
  499. #ifdef L_decodeh
  500. void __decode_header(unsigned char *data,
  501. struct resolv_header *h)
  502. {
  503. h->id = (data[0] << 8) | data[1];
  504. h->qr = (data[2] & 0x80) ? 1 : 0;
  505. h->opcode = (data[2] >> 3) & 0x0f;
  506. h->aa = (data[2] & 0x04) ? 1 : 0;
  507. h->tc = (data[2] & 0x02) ? 1 : 0;
  508. h->rd = (data[2] & 0x01) ? 1 : 0;
  509. h->ra = (data[3] & 0x80) ? 1 : 0;
  510. h->rcode = data[3] & 0x0f;
  511. h->qdcount = (data[4] << 8) | data[5];
  512. h->ancount = (data[6] << 8) | data[7];
  513. h->nscount = (data[8] << 8) | data[9];
  514. h->arcount = (data[10] << 8) | data[11];
  515. }
  516. #endif /* L_decodeh */
  517. #ifdef L_encodeq
  518. int __encode_question(const struct resolv_question *q,
  519. unsigned char *dest,
  520. int maxlen)
  521. {
  522. int i;
  523. i = __encode_dotted(q->dotted, dest, maxlen);
  524. if (i < 0)
  525. return i;
  526. dest += i;
  527. maxlen -= i;
  528. if (maxlen < 4)
  529. return -1;
  530. dest[0] = (q->qtype & 0xff00) >> 8;
  531. dest[1] = (q->qtype & 0x00ff) >> 0;
  532. dest[2] = (q->qclass & 0xff00) >> 8;
  533. dest[3] = (q->qclass & 0x00ff) >> 0;
  534. return i + 4;
  535. }
  536. #endif /* L_encodeq */
  537. #ifdef L_encodea
  538. int __encode_answer(struct resolv_answer *a, unsigned char *dest, int maxlen)
  539. {
  540. int i;
  541. i = __encode_dotted(a->dotted, dest, maxlen);
  542. if (i < 0)
  543. return i;
  544. dest += i;
  545. maxlen -= i;
  546. if (maxlen < (RRFIXEDSZ + a->rdlength))
  547. return -1;
  548. *dest++ = (a->atype & 0xff00) >> 8;
  549. *dest++ = (a->atype & 0x00ff) >> 0;
  550. *dest++ = (a->aclass & 0xff00) >> 8;
  551. *dest++ = (a->aclass & 0x00ff) >> 0;
  552. *dest++ = (a->ttl & 0xff000000) >> 24;
  553. *dest++ = (a->ttl & 0x00ff0000) >> 16;
  554. *dest++ = (a->ttl & 0x0000ff00) >> 8;
  555. *dest++ = (a->ttl & 0x000000ff) >> 0;
  556. *dest++ = (a->rdlength & 0xff00) >> 8;
  557. *dest++ = (a->rdlength & 0x00ff) >> 0;
  558. memcpy(dest, a->rdata, a->rdlength);
  559. return i + RRFIXEDSZ + a->rdlength;
  560. }
  561. #endif /* L_encodea */
  562. #ifdef CURRENTLY_UNUSED
  563. #ifdef L_encodep
  564. int __encode_packet(struct resolv_header *h,
  565. struct resolv_question **q,
  566. struct resolv_answer **an,
  567. struct resolv_answer **ns,
  568. struct resolv_answer **ar,
  569. unsigned char *dest, int maxlen) attribute_hidden;
  570. int __encode_packet(struct resolv_header *h,
  571. struct resolv_question **q,
  572. struct resolv_answer **an,
  573. struct resolv_answer **ns,
  574. struct resolv_answer **ar,
  575. unsigned char *dest, int maxlen)
  576. {
  577. int i, total = 0;
  578. unsigned j;
  579. i = __encode_header(h, dest, maxlen);
  580. if (i < 0)
  581. return i;
  582. dest += i;
  583. maxlen -= i;
  584. total += i;
  585. for (j = 0; j < h->qdcount; j++) {
  586. i = __encode_question(q[j], dest, maxlen);
  587. if (i < 0)
  588. return i;
  589. dest += i;
  590. maxlen -= i;
  591. total += i;
  592. }
  593. for (j = 0; j < h->ancount; j++) {
  594. i = __encode_answer(an[j], dest, maxlen);
  595. if (i < 0)
  596. return i;
  597. dest += i;
  598. maxlen -= i;
  599. total += i;
  600. }
  601. for (j = 0; j < h->nscount; j++) {
  602. i = __encode_answer(ns[j], dest, maxlen);
  603. if (i < 0)
  604. return i;
  605. dest += i;
  606. maxlen -= i;
  607. total += i;
  608. }
  609. for (j = 0; j < h->arcount; j++) {
  610. i = __encode_answer(ar[j], dest, maxlen);
  611. if (i < 0)
  612. return i;
  613. dest += i;
  614. maxlen -= i;
  615. total += i;
  616. }
  617. return total;
  618. }
  619. #endif /* L_encodep */
  620. #ifdef L_decodep
  621. int __decode_packet(unsigned char *data, struct resolv_header *h) attribute_hidden;
  622. int __decode_packet(unsigned char *data, struct resolv_header *h)
  623. {
  624. __decode_header(data, h);
  625. return HFIXEDSZ;
  626. }
  627. #endif /* L_decodep */
  628. #ifdef L_formquery
  629. int __form_query(int id,
  630. const char *name,
  631. int type,
  632. unsigned char *packet,
  633. int maxlen) attribute_hidden;
  634. int __form_query(int id,
  635. const char *name,
  636. int type,
  637. unsigned char *packet,
  638. int maxlen)
  639. {
  640. struct resolv_header h;
  641. struct resolv_question q;
  642. int i, j;
  643. memset(&h, 0, sizeof(h));
  644. h.id = id;
  645. h.qdcount = 1;
  646. q.dotted = (char *) name;
  647. q.qtype = type;
  648. q.qclass = C_IN; /* CLASS_IN */
  649. i = __encode_header(&h, packet, maxlen);
  650. if (i < 0)
  651. return i;
  652. j = __encode_question(&q, packet + i, maxlen - i);
  653. if (j < 0)
  654. return j;
  655. return i + j;
  656. }
  657. #endif /* L_formquery */
  658. #endif /* CURRENTLY_UNUSED */
  659. #ifdef L_opennameservers
  660. # if __BYTE_ORDER == __LITTLE_ENDIAN
  661. #define NAMESERVER_PORT_N (__bswap_constant_16(NAMESERVER_PORT))
  662. #else
  663. #define NAMESERVER_PORT_N NAMESERVER_PORT
  664. #endif
  665. __UCLIBC_MUTEX_INIT(__resolv_lock, PTHREAD_MUTEX_INITIALIZER);
  666. /* Protected by __resolv_lock */
  667. void (*__res_sync)(void);
  668. /*uint32_t __resolv_opts; */
  669. uint8_t __resolv_timeout = RES_TIMEOUT;
  670. uint8_t __resolv_attempts = RES_DFLRETRY;
  671. unsigned __nameservers;
  672. unsigned __searchdomains;
  673. sockaddr46_t *__nameserver;
  674. char **__searchdomain;
  675. #ifdef __UCLIBC_HAS_IPV4__
  676. const struct sockaddr_in __local_nameserver = {
  677. .sin_family = AF_INET,
  678. .sin_port = NAMESERVER_PORT_N,
  679. };
  680. #else
  681. const struct sockaddr_in6 __local_nameserver = {
  682. .sin6_family = AF_INET6,
  683. .sin6_port = NAMESERVER_PORT_N,
  684. };
  685. #endif
  686. /* Helpers. Both stop on EOL, if it's '\n', it is converted to NUL first */
  687. static char *skip_nospace(char *p)
  688. {
  689. while (*p != '\0' && !isspace(*p)) {
  690. if (*p == '\n') {
  691. *p = '\0';
  692. break;
  693. }
  694. p++;
  695. }
  696. return p;
  697. }
  698. static char *skip_and_NUL_space(char *p)
  699. {
  700. /* NB: '\n' is not isspace! */
  701. while (1) {
  702. char c = *p;
  703. if (c == '\0' || !isspace(c))
  704. break;
  705. *p = '\0';
  706. if (c == '\n' || c == '#')
  707. break;
  708. p++;
  709. }
  710. return p;
  711. }
  712. /* Must be called under __resolv_lock. */
  713. void __open_nameservers(void)
  714. {
  715. static uint32_t resolv_conf_mtime;
  716. char szBuffer[MAXLEN_searchdomain];
  717. FILE *fp;
  718. int i;
  719. sockaddr46_t sa;
  720. if (!__res_sync) {
  721. /* Reread /etc/resolv.conf if it was modified. */
  722. struct stat sb;
  723. if (stat(_PATH_RESCONF, &sb) != 0)
  724. sb.st_mtime = 0;
  725. if (resolv_conf_mtime != (uint32_t)sb.st_mtime) {
  726. resolv_conf_mtime = sb.st_mtime;
  727. __close_nameservers(); /* force config reread */
  728. }
  729. }
  730. if (__nameservers)
  731. goto sync;
  732. __resolv_timeout = RES_TIMEOUT;
  733. __resolv_attempts = RES_DFLRETRY;
  734. fp = fopen(_PATH_RESCONF, "r");
  735. #ifdef FALLBACK_TO_CONFIG_RESOLVCONF
  736. if (!fp) {
  737. /* If we do not have a pre-populated /etc/resolv.conf then
  738. try to use the one from /etc/config which exists on numerous
  739. systems ranging from some uClinux to IRIX installations and
  740. may be the only /etc dir that was mounted rw. */
  741. fp = fopen("/etc/config/resolv.conf", "r");
  742. }
  743. #endif
  744. if (fp) {
  745. while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
  746. void *ptr;
  747. char *keyword, *p;
  748. keyword = p = skip_and_NUL_space(szBuffer);
  749. /* skip keyword */
  750. p = skip_nospace(p);
  751. /* find next word */
  752. p = skip_and_NUL_space(p);
  753. if (strcmp(keyword, "nameserver") == 0) {
  754. /* terminate IP addr */
  755. *skip_nospace(p) = '\0';
  756. memset(&sa, 0, sizeof(sa));
  757. if (0) /* nothing */;
  758. #ifdef __UCLIBC_HAS_IPV6__
  759. else if (inet_pton(AF_INET6, p, &sa.sa6.sin6_addr) > 0) {
  760. sa.sa6.sin6_family = AF_INET6;
  761. sa.sa6.sin6_port = htons(NAMESERVER_PORT);
  762. }
  763. #endif
  764. #ifdef __UCLIBC_HAS_IPV4__
  765. else if (inet_pton(AF_INET, p, &sa.sa4.sin_addr) > 0) {
  766. sa.sa4.sin_family = AF_INET;
  767. sa.sa4.sin_port = htons(NAMESERVER_PORT);
  768. }
  769. #endif
  770. else
  771. continue; /* garbage on this line */
  772. ptr = realloc(__nameserver, (__nameservers + 1) * sizeof(__nameserver[0]));
  773. if (!ptr)
  774. continue;
  775. __nameserver = ptr;
  776. __nameserver[__nameservers++] = sa; /* struct copy */
  777. continue;
  778. }
  779. if (strcmp(keyword, "domain") == 0 || strcmp(keyword, "search") == 0) {
  780. char *p1;
  781. /* free old domains ("last 'domain' or 'search' wins" rule) */
  782. while (__searchdomains)
  783. free(__searchdomain[--__searchdomains]);
  784. /*free(__searchdomain);*/
  785. /*__searchdomain = NULL; - not necessary */
  786. next_word:
  787. /* terminate current word */
  788. p1 = skip_nospace(p);
  789. /* find next word (maybe) */
  790. p1 = skip_and_NUL_space(p1);
  791. /* add it */
  792. ptr = realloc(__searchdomain, (__searchdomains + 1) * sizeof(__searchdomain[0]));
  793. if (!ptr)
  794. continue;
  795. __searchdomain = ptr;
  796. /* NB: strlen(p) <= MAXLEN_searchdomain) because szBuffer[] is smaller */
  797. ptr = strdup(p);
  798. if (!ptr)
  799. continue;
  800. DPRINTF("adding search %s\n", (char*)ptr);
  801. __searchdomain[__searchdomains++] = (char*)ptr;
  802. p = p1;
  803. if (*p)
  804. goto next_word;
  805. continue;
  806. }
  807. /* if (strcmp(keyword, "sortlist") == 0)... */
  808. if (strcmp(keyword, "options") == 0) {
  809. char *p1;
  810. uint8_t *what;
  811. if (p == NULL || (p1 = strchr(p, ':')) == NULL)
  812. continue;
  813. *p1++ = '\0';
  814. if (strcmp(p, "timeout") == 0)
  815. what = &__resolv_timeout;
  816. else if (strcmp(p, "attempts") == 0)
  817. what = &__resolv_attempts;
  818. else
  819. continue;
  820. *what = atoi(p1);
  821. DPRINTF("option %s:%d\n", p, *what);
  822. }
  823. }
  824. fclose(fp);
  825. }
  826. if (__nameservers == 0) {
  827. /* Have to handle malloc failure! What a mess...
  828. * And it's not only here, we need to be careful
  829. * to never write into __nameserver[0] if it points
  830. * to constant __local_nameserver, or free it. */
  831. __nameserver = malloc(sizeof(__nameserver[0]));
  832. if (__nameserver)
  833. memcpy(__nameserver, &__local_nameserver, sizeof(__local_nameserver));
  834. else
  835. __nameserver = (void*) &__local_nameserver;
  836. __nameservers++;
  837. }
  838. if (__searchdomains == 0) {
  839. char buf[256];
  840. char *p;
  841. i = gethostname(buf, sizeof(buf) - 1);
  842. buf[sizeof(buf) - 1] = '\0';
  843. if (i == 0 && (p = strchr(buf, '.')) != NULL && p[1]) {
  844. p = strdup(p + 1);
  845. if (!p)
  846. goto err;
  847. __searchdomain = malloc(sizeof(__searchdomain[0]));
  848. if (!__searchdomain) {
  849. free(p);
  850. goto err;
  851. }
  852. __searchdomain[0] = p;
  853. __searchdomains++;
  854. err: ;
  855. }
  856. }
  857. DPRINTF("nameservers = %d\n", __nameservers);
  858. sync:
  859. if (__res_sync)
  860. __res_sync();
  861. }
  862. #endif /* L_opennameservers */
  863. #ifdef L_closenameservers
  864. /* Must be called under __resolv_lock. */
  865. void __close_nameservers(void)
  866. {
  867. if (__nameserver != (void*) &__local_nameserver)
  868. free(__nameserver);
  869. __nameserver = NULL;
  870. __nameservers = 0;
  871. while (__searchdomains)
  872. free(__searchdomain[--__searchdomains]);
  873. free(__searchdomain);
  874. __searchdomain = NULL;
  875. /*__searchdomains = 0; - already is */
  876. }
  877. #endif /* L_closenameservers */
  878. #ifdef L_dnslookup
  879. /* Helpers */
  880. static int __length_question(const unsigned char *data, int maxlen)
  881. {
  882. const unsigned char *start;
  883. unsigned b;
  884. if (!data)
  885. return -1;
  886. start = data;
  887. while (1) {
  888. if (maxlen <= 0)
  889. return -1;
  890. b = *data++;
  891. if (b == 0)
  892. break;
  893. if ((b & 0xc0) == 0xc0) {
  894. /* It's a "compressed" name. */
  895. data++; /* skip lsb of redirected offset */
  896. maxlen -= 2;
  897. break;
  898. }
  899. data += b;
  900. maxlen -= (b + 1); /* account for data++ above */
  901. }
  902. /* Up to here we were skipping encoded name */
  903. /* Account for QTYPE and QCLASS fields */
  904. if (maxlen < 4)
  905. return -1;
  906. return data - start + 2 + 2;
  907. }
  908. static int __decode_answer(const unsigned char *message, /* packet */
  909. int offset,
  910. int len, /* total packet len */
  911. struct resolv_answer *a)
  912. {
  913. char temp[256];
  914. int i;
  915. DPRINTF("decode_answer(start): off %d, len %d\n", offset, len);
  916. i = __decode_dotted(message, offset, len, temp, sizeof(temp));
  917. if (i < 0)
  918. return i;
  919. message += offset + i;
  920. len -= i + RRFIXEDSZ + offset;
  921. if (len < 0) {
  922. DPRINTF("decode_answer: off %d, len %d, i %d\n", offset, len, i);
  923. return len;
  924. }
  925. /* TODO: what if strdup fails? */
  926. a->dotted = strdup(temp);
  927. a->atype = (message[0] << 8) | message[1];
  928. message += 2;
  929. a->aclass = (message[0] << 8) | message[1];
  930. message += 2;
  931. a->ttl = (message[0] << 24) |
  932. (message[1] << 16) | (message[2] << 8) | (message[3] << 0);
  933. message += 4;
  934. a->rdlength = (message[0] << 8) | message[1];
  935. message += 2;
  936. a->rdata = message;
  937. a->rdoffset = offset + i + RRFIXEDSZ;
  938. DPRINTF("i=%d,rdlength=%d\n", i, a->rdlength);
  939. if (len < a->rdlength)
  940. return -1;
  941. return i + RRFIXEDSZ + a->rdlength;
  942. }
  943. #if defined __UCLIBC_DNSRAND_MODE_URANDOM__ || defined __UCLIBC_DNSRAND_MODE_PRNGPLUS__
  944. /*
  945. * Get a random int from urandom.
  946. * Return 0 on success and -1 on failure.
  947. *
  948. * This will dip into the entropy pool maintaind by the system.
  949. */
  950. int _dnsrand_getrandom_urandom(int *rand_value) {
  951. static int urand_fd = -1;
  952. static int errCnt = 0;
  953. if (urand_fd == -1) {
  954. urand_fd = open("/dev/urandom", O_RDONLY);
  955. if (urand_fd == -1) {
  956. if ((errCnt % 16) == 0) {
  957. DPRINTF("uCLibC:WARN:DnsRandGetRand: urandom is unavailable...\n");
  958. }
  959. errCnt += 1;
  960. return -1;
  961. }
  962. }
  963. if (read(urand_fd, rand_value, sizeof(int)) == sizeof(int)) { /* small reads like few bytes here should be safe in general. */
  964. DPRINTF("uCLibC:DBUG:DnsRandGetRand: URandom:0x%lx\n", *rand_value);
  965. return 0;
  966. }
  967. return -1;
  968. }
  969. #endif
  970. #if defined __UCLIBC_DNSRAND_MODE_CLOCK__ || defined __UCLIBC_DNSRAND_MODE_PRNGPLUS__
  971. /*
  972. * Try get a sort of random int by looking at current time in system realtime clock.
  973. * Return 0 on success and -1 on failure.
  974. *
  975. * This requries the realtime related uclibc feature to be enabled and also
  976. * the system should have a clock source with nanosec resolution to be mapped
  977. * to CLOCK_REALTIME, for this to generate values that appear random plausibly.
  978. */
  979. int _dnsrand_getrandom_clock(int *rand_value) {
  980. #if defined __USE_POSIX199309 && defined __UCLIBC_HAS_REALTIME__
  981. struct timespec ts;
  982. if (clock_gettime(CLOCK_REALTIME, &ts) == 0) {
  983. *rand_value = (ts.tv_sec + ts.tv_nsec) % INT_MAX;
  984. DPRINTF("uCLibC:DBUG:DnsRandGetRand: Clock:0x%lx\n", *rand_value);
  985. return 0;
  986. }
  987. #endif
  988. return -1;
  989. }
  990. #endif
  991. #ifdef __UCLIBC_DNSRAND_MODE_PRNGPLUS__
  992. /*
  993. * Try get a random int by first checking at urandom and then at realtime clock.
  994. * Return 0 on success and -1 on failure.
  995. *
  996. * Chances are most embedded targets using linux/bsd/... could have urandom and
  997. * also it can potentially give better random values, so try urandom first.
  998. * However if there is failure wrt urandom, then try realtime clock based helper.
  999. */
  1000. int _dnsrand_getrandom_urcl(int *rand_value) {
  1001. if (_dnsrand_getrandom_urandom(rand_value) == 0) {
  1002. return 0;
  1003. }
  1004. if (_dnsrand_getrandom_clock(rand_value) == 0) {
  1005. return 0;
  1006. }
  1007. DPRINTF("uCLibC:DBUG:DnsRandGetRand: URCL:Nothing:0x%lx\n", *rand_value);
  1008. return -1;
  1009. }
  1010. #define DNSRAND_PRNGSTATE_INT32LEN 32
  1011. #undef DNSRAND_PRNGRUN_SHORT
  1012. #ifdef DNSRAND_PRNGRUN_SHORT
  1013. #define DNSRAND_RESEED_OP1 (DNSRAND_PRNGSTATE_INT32LEN/2)
  1014. #define DNSRAND_RESEED_OP2 (DNSRAND_PRNGSTATE_INT32LEN/4)
  1015. #else
  1016. #define DNSRAND_RESEED_OP1 (DNSRAND_PRNGSTATE_INT32LEN*6)
  1017. #define DNSRAND_RESEED_OP2 DNSRAND_PRNGSTATE_INT32LEN
  1018. #endif
  1019. #define DNSRAND_TIMEFORCED_RESEED_CHECKMOD (DNSRAND_PRNGSTATE_INT32LEN/8)
  1020. #define DNSRAND_TIMEFORCED_RESEED_SECS 120
  1021. time_t clock_getcursec(void) {
  1022. static time_t dummyTime = 0;
  1023. #if defined __USE_POSIX199309 && defined __UCLIBC_HAS_REALTIME__
  1024. struct timespec ts;
  1025. if (clock_gettime(CLOCK_REALTIME, &ts) == 0) {
  1026. return ts.tv_sec;
  1027. }
  1028. #endif
  1029. dummyTime += DNSRAND_TIMEFORCED_RESEED_SECS;
  1030. return dummyTime;
  1031. }
  1032. /*
  1033. * This logic uses uclibc's random PRNG to generate random int. This keeps the
  1034. * logic fast by not depending on a more involved CPRNG kind of logic nor on a
  1035. * kernel to user space handshake at the core.
  1036. *
  1037. * However to ensure that pseudo random sequences based on a given seeding of the
  1038. * PRNG logic, is not generated for too long so as to allow a advarsary to try guess
  1039. * the internal states of the prng logic and inturn the next number, srandom is
  1040. * used periodically to reseed PRNG logic, when and where possible.
  1041. *
  1042. * To help with this periodic reseeding, by default the logic will first try to
  1043. * see if it can get some relatively random number using /dev/urandom. If not it
  1044. * will try use the current time to generate plausibly random value as substitute.
  1045. * If neither of these sources are available, then the prng itself is used to seed
  1046. * a new state, so that the pseudo random sequence can continue, which is better
  1047. * than the fallback simple counter.
  1048. *
  1049. * Also to add bit more of variance wrt this periodic reseeding, the period interval
  1050. * at which this reseeding occurs keeps changing within a predefined window. The
  1051. * window is controlled based on how often this logic is called (which currently
  1052. * will depend on how often requests for dns query (and inturn dnsrand_next) occurs,
  1053. * as well as a self driven periodically changing request count boundry.
  1054. *
  1055. * The internally generated random values are not directly exposed, instead result
  1056. * of adjacent values large mult with mod is used to greatly reduce the possibility
  1057. * of trying to infer the internal values from externally exposed random values.
  1058. * This should also make longer run of prng ok to an extent.
  1059. *
  1060. * NOTE: The Random PRNG used here maintains its own internal state data, so that
  1061. * it doesnt impact any other users of random prng calls in the system/program
  1062. * compiled against uclibc.
  1063. *
  1064. * NOTE: If your target doesnt support int64_t, then the code uses XOR instead of
  1065. * mult with mod based transform on the internal random sequence, to generate the
  1066. * random number that is returned. However as XOR is not a one way transform, this
  1067. * is supported only in DNSRAND_PRNGRUN_SHORT mode by default, which needs to be
  1068. * explicitly enabled by the platform developer, by defining the same.
  1069. *
  1070. */
  1071. int _dnsrand_getrandom_prng(int *rand_value) {
  1072. static time_t reSeededSec = 0;
  1073. time_t curSec = 0;
  1074. bool bTimeForcedReSeed = 0;
  1075. static int cnt = -1;
  1076. static int nextReSeedWindow = DNSRAND_RESEED_OP1;
  1077. static int32_t prngState[DNSRAND_PRNGSTATE_INT32LEN]; /* prng logic internally assumes int32_t wrt state array, so to help align if required */
  1078. static struct random_data prngData;
  1079. int32_t val, val2;
  1080. int calc;
  1081. int prngSeed = 0x19481869;
  1082. if (cnt == -1) {
  1083. _dnsrand_getrandom_urcl(&prngSeed);
  1084. memset(&prngData, 0, sizeof(prngData));
  1085. initstate_r(prngSeed, (char*)&prngState, DNSRAND_PRNGSTATE_INT32LEN*4, &prngData);
  1086. }
  1087. cnt += 1;
  1088. if ((cnt % DNSRAND_TIMEFORCED_RESEED_CHECKMOD) == 0) {
  1089. curSec = clock_getcursec();
  1090. if ((curSec - reSeededSec) >= DNSRAND_TIMEFORCED_RESEED_SECS) {
  1091. bTimeForcedReSeed = 1;
  1092. }
  1093. }
  1094. if (((cnt % nextReSeedWindow) == 0) || bTimeForcedReSeed) {
  1095. if (curSec == 0) curSec = clock_getcursec();
  1096. reSeededSec = curSec;
  1097. if (_dnsrand_getrandom_urcl(&prngSeed) != 0) {
  1098. random_r(&prngData, &prngSeed);
  1099. }
  1100. srandom_r(prngSeed, &prngData);
  1101. random_r(&prngData, &val);
  1102. nextReSeedWindow = DNSRAND_RESEED_OP1 + (val % DNSRAND_RESEED_OP2);
  1103. DPRINTF("uCLibC:DBUG:DnsRandNext: PRNGWindow:%d\n", nextReSeedWindow);
  1104. cnt = 0;
  1105. }
  1106. random_r(&prngData, &val);
  1107. random_r(&prngData, &val2);
  1108. #ifdef INT64_MAX
  1109. calc = ((int64_t)val * (int64_t)val2) % INT_MAX;
  1110. #else
  1111. # ifdef DNSRAND_PRNGRUN_SHORT
  1112. calc = val ^ val2;
  1113. # warning "[No int64] using xor based random number transform logic in short prng run mode, bcas int64_t not supported on this target"
  1114. # else
  1115. # error "[No int64] using xor based random number transform logic only supported with short prng runs, you may want to define DNSRAND_PRNGRUN_SHORT"
  1116. # endif
  1117. #endif
  1118. *rand_value = calc;
  1119. DPRINTF("uCLibC:DBUG:DnsRandGetRand: PRNGPlus: %d, 0x%lx 0x%lx 0x%lx\n", cnt, val, val2, *rand_value);
  1120. return 0;
  1121. }
  1122. #endif
  1123. /**
  1124. * If DNS query's id etal is generated using a simple counter, then it can be
  1125. * subjected to dns poisoning relatively easily, so adding some randomness can
  1126. * increase the difficulty wrt dns poisoning and is thus desirable.
  1127. *
  1128. * However given that embedded targets may or may not have different sources available
  1129. * with them to try generate random values, this logic tries to provides flexibility
  1130. * to the platform developer to decide, how they may want to handle this.
  1131. *
  1132. * If a given target doesnt support urandom nor realtime clock OR for some reason
  1133. * if the platform developer doesnt want to use random dns query id etal, then
  1134. * they can define __UCLIBC_DNSRAND_MODE_SIMPLECOUNTER__ so that a simple incrementing
  1135. * counter is used.
  1136. *
  1137. * However if the target has support for urandom or realtime clock, then the prngplus
  1138. * based random generation tries to give a good balance between randomness and performance.
  1139. * This is the default and is enabled when no other mode is defined. It is also indirectly
  1140. * enabled by defining __UCLIBC_DNSRAND_MODE_PRNGPLUS__ instead of the other modes.
  1141. *
  1142. * If urandom is available on the target and one wants to keep things simple and use
  1143. * it directly, then one can define __UCLIBC_DNSRAND_MODE_URANDOM__. Do note that this
  1144. * will be relatively slower compared to other options. But it can normally generate
  1145. * good random values/ids by dipping into the entropy pool available in the system.
  1146. *
  1147. * If system realtime clock is available on target and enabled, then if one wants to
  1148. * keep things simple and use it directly, then define __UCLIBC_DNSRAND_MODE_CLOCK__.
  1149. * Do note that this requires nanosecond resolution / granularity wrt the realtime
  1150. * clock source to generate plausibly random values/ids. As processor &/ io performance
  1151. * improves, the effectiveness of this strategy can be impacted in some cases.
  1152. *
  1153. * If either the URandom or Clock based get random fails, then the logic is setup to
  1154. * try fallback to the simple counter mode, with the help of the def_value, which is
  1155. * setup to be the next increment wrt the previously generated / used value, by the
  1156. * caller of dnsrand_next.
  1157. *
  1158. */
  1159. int dnsrand_next(int def_value) {
  1160. int val = def_value;
  1161. #if defined __UCLIBC_DNSRAND_MODE_SIMPLECOUNTER__
  1162. return val;
  1163. #elif defined __UCLIBC_DNSRAND_MODE_URANDOM__
  1164. if (_dnsrand_getrandom_urandom(&val) == 0) {
  1165. return val;
  1166. }
  1167. return def_value;
  1168. #elif defined __UCLIBC_DNSRAND_MODE_CLOCK__
  1169. if (_dnsrand_getrandom_clock(&val) == 0) {
  1170. return val;
  1171. }
  1172. return def_value;
  1173. #else
  1174. if (_dnsrand_getrandom_prng(&val) == 0) {
  1175. return val;
  1176. }
  1177. return def_value;
  1178. #endif
  1179. }
  1180. int dnsrand_setup(int def_value) {
  1181. return def_value;
  1182. }
  1183. /* On entry:
  1184. * a.buf(len) = auxiliary buffer for IP addresses after first one
  1185. * a.add_count = how many additional addresses are there already
  1186. * outpacket = where to save ptr to raw packet? can be NULL
  1187. * On exit:
  1188. * ret < 0: error, all other data is not valid
  1189. * ret >= 0: length of reply packet
  1190. * a.add_count & a.buf: updated
  1191. * a.rdlength: length of addresses (4 bytes for IPv4)
  1192. * *outpacket: updated (packet is malloced, you need to free it)
  1193. * a.rdata: points into *outpacket to 1st IP addr
  1194. * NB: don't pass outpacket == NULL if you need to use a.rdata!
  1195. * a.atype: type of query?
  1196. * a.dotted: which name we _actually_ used. May contain search domains
  1197. * appended. (why the filed is called "dotted" I have no idea)
  1198. * This is a malloced string. May be NULL because strdup failed.
  1199. */
  1200. int __dns_lookup(const char *name,
  1201. int type,
  1202. unsigned char **outpacket,
  1203. struct resolv_answer *a)
  1204. {
  1205. /* Protected by __resolv_lock: */
  1206. static int last_ns_num = 0;
  1207. static uint16_t last_id = 1;
  1208. int i, j, fd, rc;
  1209. int packet_len;
  1210. int name_len;
  1211. #ifdef USE_SELECT
  1212. struct timeval tv;
  1213. fd_set fds;
  1214. #else
  1215. struct pollfd fds;
  1216. #endif
  1217. struct resolv_header h;
  1218. struct resolv_question q;
  1219. struct resolv_answer ma;
  1220. bool first_answer = 1;
  1221. int retries_left;
  1222. unsigned char *packet = malloc(PACKETSZ);
  1223. char *lookup;
  1224. int variant = -1; /* search domain to append, -1: none */
  1225. int local_ns_num = -1; /* Nth server to use */
  1226. int local_id = local_id; /* for compiler */
  1227. int sdomains = 0;
  1228. bool ends_with_dot;
  1229. bool contains_dot;
  1230. sockaddr46_t sa;
  1231. int num_answers;
  1232. fd = -1;
  1233. lookup = NULL;
  1234. name_len = strlen(name);
  1235. if ((unsigned)name_len >= MAXDNAME - MAXLEN_searchdomain - 2)
  1236. goto fail; /* paranoia */
  1237. lookup = malloc(name_len + 1/*for '.'*/ + MAXLEN_searchdomain + 1);
  1238. if (!packet || !lookup || !name[0])
  1239. goto fail;
  1240. ends_with_dot = (name[name_len - 1] == '.');
  1241. contains_dot = strchr(name, '.') != NULL;
  1242. /* no strcpy! paranoia, user might change name[] under us */
  1243. memcpy(lookup, name, name_len);
  1244. DPRINTF("Looking up type %d answer for '%s'\n", type, name);
  1245. retries_left = 0; /* for compiler */
  1246. do {
  1247. unsigned act_variant;
  1248. int pos;
  1249. unsigned reply_timeout;
  1250. if (fd != -1) {
  1251. close(fd);
  1252. fd = -1;
  1253. }
  1254. /* Mess with globals while under lock */
  1255. /* NB: even data *pointed to* by globals may vanish
  1256. * outside the locks. We should assume any and all
  1257. * globals can completely change between locked
  1258. * code regions. OTOH, this is rare, so we don't need
  1259. * to handle it "nicely" (do not skip servers,
  1260. * search domains, etc), we only need to ensure
  1261. * we do not SEGV, use freed+overwritten data
  1262. * or do other Really Bad Things. */
  1263. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  1264. __open_nameservers();
  1265. if (type != T_PTR) {
  1266. sdomains = __searchdomains;
  1267. }
  1268. lookup[name_len] = '\0';
  1269. /* For qualified names, act_variant = MAX_UINT, 0, .., sdomains-1
  1270. * => Try original name first, then append search domains
  1271. * For names without domain, act_variant = 0, 1, .., sdomains
  1272. * => Try search domains first, original name last */
  1273. act_variant = contains_dot ? variant : variant + 1;
  1274. if (act_variant < sdomains) {
  1275. /* lookup is name_len + 1 + MAXLEN_searchdomain + 1 long */
  1276. /* __searchdomain[] is not bigger than MAXLEN_searchdomain */
  1277. lookup[name_len] = '.';
  1278. strcpy(&lookup[name_len + 1], __searchdomain[act_variant]);
  1279. }
  1280. /* first time? pick starting server etc */
  1281. if (local_ns_num < 0) {
  1282. local_id = dnsrand_setup(last_id);
  1283. /*TODO: implement /etc/resolv.conf's "options rotate"
  1284. (a.k.a. RES_ROTATE bit in _res.options)
  1285. local_ns_num = 0;
  1286. if (_res.options & RES_ROTATE) */
  1287. local_ns_num = last_ns_num;
  1288. retries_left = __nameservers * __resolv_attempts;
  1289. }
  1290. if (local_ns_num >= __nameservers)
  1291. local_ns_num = 0;
  1292. local_id = dnsrand_next(++local_id);
  1293. local_id &= 0xffff;
  1294. /* write new values back while still under lock */
  1295. last_id = local_id;
  1296. last_ns_num = local_ns_num;
  1297. /* struct copy */
  1298. /* can't just take a pointer, __nameserver[x]
  1299. * is not safe to use outside of locks */
  1300. sa = __nameserver[local_ns_num];
  1301. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  1302. memset(packet, 0, PACKETSZ);
  1303. memset(&h, 0, sizeof(h));
  1304. /* encode header */
  1305. h.id = local_id;
  1306. h.qdcount = 1;
  1307. h.rd = 1;
  1308. DPRINTF("encoding header\n", h.rd);
  1309. i = __encode_header(&h, packet, PACKETSZ);
  1310. if (i < 0)
  1311. goto fail;
  1312. /* encode question */
  1313. DPRINTF("lookup name: %s\n", lookup);
  1314. q.dotted = lookup;
  1315. q.qtype = type;
  1316. q.qclass = C_IN; /* CLASS_IN */
  1317. j = __encode_question(&q, packet+i, PACKETSZ-i);
  1318. if (j < 0)
  1319. goto fail;
  1320. packet_len = i + j;
  1321. /* send packet */
  1322. #ifdef DEBUG
  1323. {
  1324. const socklen_t plen = sa.sa.sa_family == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN;
  1325. char *pbuf = malloc(plen);
  1326. if (pbuf == NULL) ;/* nothing */
  1327. #ifdef __UCLIBC_HAS_IPV6__
  1328. else if (sa.sa.sa_family == AF_INET6)
  1329. pbuf = (char*)inet_ntop(AF_INET6, &sa.sa6.sin6_addr, pbuf, plen);
  1330. #endif
  1331. #ifdef __UCLIBC_HAS_IPV4__
  1332. else if (sa.sa.sa_family == AF_INET)
  1333. pbuf = (char*)inet_ntop(AF_INET, &sa.sa4.sin_addr, pbuf, plen);
  1334. #endif
  1335. DPRINTF("On try %d, sending query to %s, port %d\n",
  1336. retries_left, pbuf, NAMESERVER_PORT);
  1337. free(pbuf);
  1338. }
  1339. #endif
  1340. fd = socket(sa.sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
  1341. if (fd < 0) /* paranoia */
  1342. goto try_next_server;
  1343. rc = connect(fd, &sa.sa, sizeof(sa));
  1344. if (rc < 0) {
  1345. /*if (errno == ENETUNREACH) { */
  1346. /* routing error, presume not transient */
  1347. goto try_next_server;
  1348. /*} */
  1349. /*For example, what transient error this can be? Can't think of any */
  1350. /* retry */
  1351. /*continue; */
  1352. }
  1353. DPRINTF("Xmit packet len:%d id:%d qr:%d\n", packet_len, h.id, h.qr);
  1354. /* no error check - if it fails, we time out on recv */
  1355. send(fd, packet, packet_len, 0);
  1356. #ifdef USE_SELECT
  1357. reply_timeout = __resolv_timeout;
  1358. wait_again:
  1359. FD_ZERO(&fds);
  1360. FD_SET(fd, &fds);
  1361. tv.tv_sec = reply_timeout;
  1362. tv.tv_usec = 0;
  1363. if (select(fd + 1, &fds, NULL, NULL, &tv) <= 0) {
  1364. DPRINTF("Timeout\n");
  1365. /* timed out, so retry send and receive
  1366. * to next nameserver */
  1367. goto try_next_server;
  1368. }
  1369. reply_timeout--;
  1370. #else /* !USE_SELECT */
  1371. reply_timeout = __resolv_timeout * 1000;
  1372. wait_again:
  1373. fds.fd = fd;
  1374. fds.events = POLLIN;
  1375. if (poll(&fds, 1, reply_timeout) <= 0) {
  1376. DPRINTF("Timeout\n");
  1377. /* timed out, so retry send and receive
  1378. * to next nameserver */
  1379. goto try_next_server;
  1380. }
  1381. if (fds.revents & (POLLERR | POLLHUP | POLLNVAL)) {
  1382. DPRINTF("Bad event\n");
  1383. goto try_next_server;
  1384. }
  1385. /*TODO: better timeout accounting?*/
  1386. reply_timeout -= 1000;
  1387. #endif /* USE_SELECT */
  1388. /* vda: a bogus response seen in real world (caused SEGV in uclibc):
  1389. * "ping www.google.com" sending AAAA query and getting
  1390. * response with one answer... with answer part missing!
  1391. * Fixed by thorough checks for not going past the packet's end.
  1392. */
  1393. #ifdef DEBUG
  1394. {
  1395. static const char test_query[32] = "\0\2\1\0\0\1\0\0\0\0\0\0\3www\6google\3com\0\0\34\0\1";
  1396. static const char test_respn[32] = "\0\2\201\200\0\1\0\1\0\0\0\0\3www\6google\3com\0\0\34\0\1";
  1397. pos = memcmp(packet + 2, test_query + 2, 30);
  1398. packet_len = recv(fd, packet, PACKETSZ, MSG_DONTWAIT);
  1399. if (pos == 0) {
  1400. packet_len = 32;
  1401. memcpy(packet + 2, test_respn + 2, 30);
  1402. }
  1403. }
  1404. #else
  1405. packet_len = recv(fd, packet, PACKETSZ, MSG_DONTWAIT);
  1406. #endif
  1407. if (packet_len < HFIXEDSZ) {
  1408. /* too short!
  1409. * If the peer did shutdown then retry later,
  1410. * try next peer on error.
  1411. * it's just a bogus packet from somewhere */
  1412. bogus_packet:
  1413. if (packet_len >= 0 && reply_timeout)
  1414. goto wait_again;
  1415. goto try_next_server;
  1416. }
  1417. __decode_header(packet, &h);
  1418. DPRINTF("len:%d id:%d qr:%d\n", packet_len, h.id, h.qr);
  1419. if (h.id != local_id || !h.qr) {
  1420. /* unsolicited */
  1421. goto bogus_packet;
  1422. }
  1423. DPRINTF("Got response (i think)!\n");
  1424. DPRINTF("qrcount=%d,ancount=%d,nscount=%d,arcount=%d\n",
  1425. h.qdcount, h.ancount, h.nscount, h.arcount);
  1426. DPRINTF("opcode=%d,aa=%d,tc=%d,rd=%d,ra=%d,rcode=%d\n",
  1427. h.opcode, h.aa, h.tc, h.rd, h.ra, h.rcode);
  1428. /* bug 660 says we treat negative response as an error
  1429. * and retry, which is, eh, an error. :)
  1430. * We were incurring long delays because of this. */
  1431. if (h.rcode == NXDOMAIN || h.rcode == SERVFAIL) {
  1432. /* if possible, try next search domain */
  1433. if (!ends_with_dot) {
  1434. DPRINTF("variant:%d sdomains:%d\n", variant, sdomains);
  1435. if (variant < sdomains - 1) {
  1436. /* next search domain */
  1437. variant++;
  1438. continue;
  1439. }
  1440. /* no more search domains to try */
  1441. }
  1442. if (h.rcode != SERVFAIL) {
  1443. /* dont loop, this is "no such host" situation */
  1444. h_errno = HOST_NOT_FOUND;
  1445. goto fail1;
  1446. }
  1447. }
  1448. /* Insert other non-fatal errors here, which do not warrant
  1449. * switching to next nameserver */
  1450. /* Strange error, assuming this nameserver is feeling bad */
  1451. if (h.rcode != 0)
  1452. goto try_next_server;
  1453. /* Code below won't work correctly with h.ancount == 0, so... */
  1454. if (h.ancount <= 0) {
  1455. h_errno = NO_DATA; /* [is this correct code to check for?] */
  1456. goto fail1;
  1457. }
  1458. pos = HFIXEDSZ;
  1459. /*XXX TODO: check that question matches query (and qdcount==1?) */
  1460. for (j = 0; j < h.qdcount; j++) {
  1461. DPRINTF("Skipping question %d at %d\n", j, pos);
  1462. i = __length_question(packet + pos, packet_len - pos);
  1463. if (i < 0) {
  1464. DPRINTF("Packet'question section "
  1465. "is truncated, trying next server\n");
  1466. goto try_next_server;
  1467. }
  1468. pos += i;
  1469. DPRINTF("Length of question %d is %d\n", j, i);
  1470. }
  1471. DPRINTF("Decoding answer at pos %d\n", pos);
  1472. first_answer = 1;
  1473. num_answers = 0;
  1474. a->dotted = NULL;
  1475. for (j = 0; j < h.ancount; j++) {
  1476. i = __decode_answer(packet, pos, packet_len, &ma);
  1477. if (i < 0) {
  1478. DPRINTF("failed decode %d\n", i);
  1479. /* If the message was truncated but we have
  1480. * decoded some answers, pretend it's OK */
  1481. if (num_answers && h.tc)
  1482. break;
  1483. goto try_next_server;
  1484. }
  1485. pos += i;
  1486. if (__hnbad(ma.dotted))
  1487. break;
  1488. ++num_answers;
  1489. if (first_answer) {
  1490. ma.buf = a->buf;
  1491. ma.buflen = a->buflen;
  1492. ma.add_count = a->add_count;
  1493. free(a->dotted);
  1494. memcpy(a, &ma, sizeof(ma));
  1495. if (a->atype != T_SIG && (NULL == a->buf || (type != T_A && type != T_AAAA)))
  1496. break;
  1497. if (a->atype != type)
  1498. continue;
  1499. a->add_count = h.ancount - j - 1;
  1500. if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen)
  1501. break;
  1502. a->add_count = 0;
  1503. first_answer = 0;
  1504. } else {
  1505. free(ma.dotted);
  1506. if (ma.atype != type)
  1507. continue;
  1508. if (a->rdlength != ma.rdlength) {
  1509. free(a->dotted);
  1510. DPRINTF("Answer address len(%u) differs from original(%u)\n",
  1511. ma.rdlength, a->rdlength);
  1512. goto try_next_server;
  1513. }
  1514. memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength);
  1515. ++a->add_count;
  1516. }
  1517. }
  1518. if (!num_answers) {
  1519. h_errno = NO_RECOVERY;
  1520. goto fail1;
  1521. }
  1522. /* Success! */
  1523. DPRINTF("Answer name = |%s|\n", a->dotted);
  1524. DPRINTF("Answer type = |%d|\n", a->atype);
  1525. if (fd != -1)
  1526. close(fd);
  1527. if (outpacket)
  1528. *outpacket = packet;
  1529. else
  1530. free(packet);
  1531. free(lookup);
  1532. return packet_len;
  1533. try_next_server:
  1534. /* Try next nameserver */
  1535. retries_left--;
  1536. local_ns_num++;
  1537. variant = -1;
  1538. } while (retries_left > 0);
  1539. fail:
  1540. h_errno = NETDB_INTERNAL;
  1541. fail1:
  1542. if (fd != -1)
  1543. close(fd);
  1544. free(lookup);
  1545. free(packet);
  1546. return -1;
  1547. }
  1548. #endif /* L_dnslookup */
  1549. #ifdef L_read_etc_hosts_r
  1550. parser_t * __open_etc_hosts(void)
  1551. {
  1552. parser_t *parser;
  1553. parser = config_open("/etc/hosts");
  1554. #ifdef FALLBACK_TO_CONFIG_RESOLVCONF
  1555. if (parser == NULL)
  1556. parser = config_open("/etc/config/hosts");
  1557. #endif
  1558. return parser;
  1559. }
  1560. #define MINTOKENS 2 /* ip address + canonical name */
  1561. #define MAXTOKENS (MINTOKENS + MAXALIASES)
  1562. #define HALISTOFF (sizeof(char*) * (MAXTOKENS + 1)) /* reserve space for list terminator */
  1563. #define INADDROFF (HALISTOFF + 2 * sizeof(char*))
  1564. int __read_etc_hosts_r(
  1565. parser_t * parser,
  1566. const char *name,
  1567. int type,
  1568. enum etc_hosts_action action,
  1569. struct hostent *result_buf,
  1570. char *buf, size_t buflen,
  1571. struct hostent **result,
  1572. int *h_errnop)
  1573. {
  1574. char **tok = NULL;
  1575. struct in_addr *h_addr0 = NULL;
  1576. const size_t aliaslen = INADDROFF +
  1577. #ifdef __UCLIBC_HAS_IPV6__
  1578. sizeof(struct in6_addr)
  1579. #else
  1580. sizeof(struct in_addr)
  1581. #endif
  1582. ;
  1583. int ret = HOST_NOT_FOUND;
  1584. /* make sure pointer is aligned */
  1585. int i = ALIGN_BUFFER_OFFSET(buf);
  1586. buf += i;
  1587. buflen -= i;
  1588. *h_errnop = NETDB_INTERNAL;
  1589. if (/* (ssize_t)buflen < 0 || */ buflen < aliaslen
  1590. || (buflen - aliaslen) < BUFSZ + 1)
  1591. return ERANGE;
  1592. if (parser == NULL)
  1593. parser = __open_etc_hosts();
  1594. if (parser == NULL) {
  1595. *result = NULL;
  1596. return errno;
  1597. }
  1598. /* Layout in buf:
  1599. * char *alias[MAXTOKENS] = {address, name, aliases...}
  1600. * char **h_addr_list[1] = {*in[6]_addr, NULL}
  1601. * struct in[6]_addr
  1602. * char line_buffer[BUFSZ+];
  1603. */
  1604. parser->data = buf;
  1605. parser->data_len = aliaslen;
  1606. parser->line_len = buflen - aliaslen;
  1607. *h_errnop = HOST_NOT_FOUND;
  1608. /* <ip>[[:space:]][<aliases>] */
  1609. while (config_read(parser, &tok, MAXTOKENS, MINTOKENS, "# \t", PARSE_NORMAL)) {
  1610. result_buf->h_aliases = tok+1;
  1611. if (action == GETHOSTENT) {
  1612. /* Return whatever the next entry happens to be. */
  1613. ;
  1614. } else if (action == GET_HOSTS_BYADDR) {
  1615. if (strcmp(name, *tok) != 0)
  1616. continue;
  1617. } else { /* GET_HOSTS_BYNAME */
  1618. int aliases = 0;
  1619. char **alias = tok + 1;
  1620. while (aliases < MAXALIASES) {
  1621. char *tmp = *(alias+aliases++);
  1622. if (tmp && strcasecmp(name, tmp) == 0)
  1623. goto found;
  1624. }
  1625. continue;
  1626. }
  1627. found:
  1628. result_buf->h_name = *(result_buf->h_aliases++);
  1629. result_buf->h_addr_list = (char**)(buf + HALISTOFF);
  1630. *(result_buf->h_addr_list + 1) = 0;
  1631. h_addr0 = (struct in_addr*)(buf + INADDROFF);
  1632. result_buf->h_addr = (char*)h_addr0;
  1633. if (0) /* nothing */;
  1634. #ifdef __UCLIBC_HAS_IPV4__
  1635. else if (type == AF_INET
  1636. && inet_pton(AF_INET, *tok, h_addr0) > 0) {
  1637. DPRINTF("Found INET\n");
  1638. result_buf->h_addrtype = AF_INET;
  1639. result_buf->h_length = sizeof(struct in_addr);
  1640. *result = result_buf;
  1641. ret = NETDB_SUCCESS;
  1642. }
  1643. #endif
  1644. #ifdef __UCLIBC_HAS_IPV6__
  1645. #define in6 ((struct in6_addr *)buf)
  1646. else if (type == AF_INET6
  1647. && inet_pton(AF_INET6, *tok, h_addr0) > 0) {
  1648. DPRINTF("Found INET6\n");
  1649. result_buf->h_addrtype = AF_INET6;
  1650. result_buf->h_length = sizeof(struct in6_addr);
  1651. *result = result_buf;
  1652. ret = NETDB_SUCCESS;
  1653. }
  1654. #endif
  1655. else {
  1656. /* continue parsing in the hope the user has multiple
  1657. * host types listed in the database like so:
  1658. * <ipv4 addr> host
  1659. * <ipv6 addr> host
  1660. * If looking for an IPv6 addr, don't bail when we got the IPv4
  1661. */
  1662. DPRINTF("Error: Found host but different address family\n");
  1663. /* NB: gethostbyname2_r depends on this feature
  1664. * to avoid looking for IPv6 addr of "localhost" etc */
  1665. ret = TRY_AGAIN;
  1666. continue;
  1667. }
  1668. break;
  1669. }
  1670. if (action != GETHOSTENT)
  1671. config_close(parser);
  1672. return ret;
  1673. #undef in6
  1674. }
  1675. #endif /* L_read_etc_hosts_r */
  1676. #ifdef L_get_hosts_byname_r
  1677. int __get_hosts_byname_r(const char *name,
  1678. int type,
  1679. struct hostent *result_buf,
  1680. char *buf,
  1681. size_t buflen,
  1682. struct hostent **result,
  1683. int *h_errnop)
  1684. {
  1685. return __read_etc_hosts_r(NULL, name, type, GET_HOSTS_BYNAME,
  1686. result_buf, buf, buflen, result, h_errnop);
  1687. }
  1688. #endif /* L_get_hosts_byname_r */
  1689. #ifdef L_get_hosts_byaddr_r
  1690. int __get_hosts_byaddr_r(const char *addr,
  1691. int len,
  1692. int type,
  1693. struct hostent *result_buf,
  1694. char *buf,
  1695. size_t buflen,
  1696. struct hostent **result,
  1697. int *h_errnop)
  1698. {
  1699. #ifndef __UCLIBC_HAS_IPV6__
  1700. char ipaddr[INET_ADDRSTRLEN];
  1701. #else
  1702. char ipaddr[INET6_ADDRSTRLEN];
  1703. #endif
  1704. switch (type) {
  1705. #ifdef __UCLIBC_HAS_IPV4__
  1706. case AF_INET:
  1707. if (len != sizeof(struct in_addr))
  1708. return 0;
  1709. break;
  1710. #endif
  1711. #ifdef __UCLIBC_HAS_IPV6__
  1712. case AF_INET6:
  1713. if (len != sizeof(struct in6_addr))
  1714. return 0;
  1715. break;
  1716. #endif
  1717. default:
  1718. return 0;
  1719. }
  1720. inet_ntop(type, addr, ipaddr, sizeof(ipaddr));
  1721. return __read_etc_hosts_r(NULL, ipaddr, type, GET_HOSTS_BYADDR,
  1722. result_buf, buf, buflen, result, h_errnop);
  1723. }
  1724. #endif /* L_get_hosts_byaddr_r */
  1725. #ifdef L_getnameinfo
  1726. int getnameinfo(const struct sockaddr *sa,
  1727. socklen_t addrlen,
  1728. char *host,
  1729. socklen_t hostlen,
  1730. char *serv,
  1731. socklen_t servlen,
  1732. unsigned flags)
  1733. {
  1734. int serrno = errno;
  1735. bool ok = 0;
  1736. struct hostent *hoste = NULL;
  1737. char domain[256];
  1738. if (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|NI_NAMEREQD|NI_DGRAM))
  1739. return EAI_BADFLAGS;
  1740. if (sa == NULL || addrlen < sizeof(sa_family_t))
  1741. return EAI_FAMILY;
  1742. if ((flags & NI_NAMEREQD) && host == NULL && serv == NULL)
  1743. return EAI_NONAME;
  1744. if (sa->sa_family == AF_LOCAL) /* valid */;
  1745. #ifdef __UCLIBC_HAS_IPV4__
  1746. else if (sa->sa_family == AF_INET) {
  1747. if (addrlen < sizeof(struct sockaddr_in))
  1748. return EAI_FAMILY;
  1749. }
  1750. #endif
  1751. #ifdef __UCLIBC_HAS_IPV6__
  1752. else if (sa->sa_family == AF_INET6) {
  1753. if (addrlen < sizeof(struct sockaddr_in6))
  1754. return EAI_FAMILY;
  1755. }
  1756. #endif
  1757. else
  1758. return EAI_FAMILY;
  1759. if (host != NULL && hostlen > 0)
  1760. switch (sa->sa_family) {
  1761. case AF_INET:
  1762. #ifdef __UCLIBC_HAS_IPV6__
  1763. case AF_INET6:
  1764. #endif
  1765. if (!(flags & NI_NUMERICHOST)) {
  1766. if (0) /* nothing */;
  1767. #ifdef __UCLIBC_HAS_IPV6__
  1768. else if (sa->sa_family == AF_INET6)
  1769. hoste = gethostbyaddr((const void *)
  1770. &(((const struct sockaddr_in6 *) sa)->sin6_addr),
  1771. sizeof(struct in6_addr), AF_INET6);
  1772. #endif
  1773. #ifdef __UCLIBC_HAS_IPV4__
  1774. else
  1775. hoste = gethostbyaddr((const void *)
  1776. &(((const struct sockaddr_in *)sa)->sin_addr),
  1777. sizeof(struct in_addr), AF_INET);
  1778. #endif
  1779. if (hoste) {
  1780. char *c;
  1781. if ((flags & NI_NOFQDN)
  1782. && (getdomainname(domain, sizeof(domain)) == 0)
  1783. && (c = strstr(hoste->h_name, domain)) != NULL
  1784. && (c != hoste->h_name) && (*(--c) == '.')
  1785. ) {
  1786. strncpy(host, hoste->h_name,
  1787. MIN(hostlen, (size_t) (c - hoste->h_name)));
  1788. host[MIN(hostlen - 1, (size_t) (c - hoste->h_name))] = '\0';
  1789. } else {
  1790. strncpy(host, hoste->h_name, hostlen);
  1791. }
  1792. ok = 1;
  1793. }
  1794. }
  1795. if (!ok) {
  1796. const char *c = NULL;
  1797. if (flags & NI_NAMEREQD) {
  1798. errno = serrno;
  1799. return EAI_NONAME;
  1800. }
  1801. if (0) /* nothing */;
  1802. #ifdef __UCLIBC_HAS_IPV6__
  1803. else if (sa->sa_family == AF_INET6) {
  1804. const struct sockaddr_in6 *sin6p;
  1805. sin6p = (const struct sockaddr_in6 *) sa;
  1806. c = inet_ntop(AF_INET6,
  1807. (const void *) &sin6p->sin6_addr,
  1808. host, hostlen);
  1809. #if 0
  1810. /* Does scope id need to be supported? */
  1811. uint32_t scopeid;
  1812. scopeid = sin6p->sin6_scope_id;
  1813. if (scopeid != 0) {
  1814. /* Buffer is >= IFNAMSIZ+1. */
  1815. char scopebuf[IFNAMSIZ + 1];
  1816. char *scopeptr;
  1817. int ni_numericscope = 0;
  1818. size_t real_hostlen = strnlen(host, hostlen);
  1819. size_t scopelen = 0;
  1820. scopebuf[0] = SCOPE_DELIMITER;
  1821. scopebuf[1] = '\0';
  1822. scopeptr = &scopebuf[1];
  1823. if (IN6_IS_ADDR_LINKLOCAL(&sin6p->sin6_addr)
  1824. || IN6_IS_ADDR_MC_LINKLOCAL(&sin6p->sin6_addr)) {
  1825. if (if_indextoname(scopeid, scopeptr) == NULL)
  1826. ++ni_numericscope;
  1827. else
  1828. scopelen = strlen(scopebuf);
  1829. } else {
  1830. ++ni_numericscope;
  1831. }
  1832. if (ni_numericscope)
  1833. scopelen = 1 + snprintf(scopeptr,
  1834. (scopebuf
  1835. + sizeof scopebuf
  1836. - scopeptr),
  1837. "%u", scopeid);
  1838. if (real_hostlen + scopelen + 1 > hostlen)
  1839. return EAI_SYSTEM;
  1840. memcpy(host + real_hostlen, scopebuf, scopelen + 1);
  1841. }
  1842. #endif
  1843. }
  1844. #endif /* __UCLIBC_HAS_IPV6__ */
  1845. #if defined __UCLIBC_HAS_IPV4__
  1846. else {
  1847. c = inet_ntop(AF_INET, (const void *)
  1848. &(((const struct sockaddr_in *) sa)->sin_addr),
  1849. host, hostlen);
  1850. }
  1851. #endif
  1852. if (c == NULL) {
  1853. errno = serrno;
  1854. return EAI_SYSTEM;
  1855. }
  1856. ok = 1;
  1857. }
  1858. break;
  1859. case AF_LOCAL:
  1860. if (!(flags & NI_NUMERICHOST)) {
  1861. struct utsname utsname;
  1862. if (!uname(&utsname)) {
  1863. strncpy(host, utsname.nodename, hostlen);
  1864. break;
  1865. };
  1866. };
  1867. if (flags & NI_NAMEREQD) {
  1868. errno = serrno;
  1869. return EAI_NONAME;
  1870. }
  1871. strncpy(host, "localhost", hostlen);
  1872. break;
  1873. /* Already checked above
  1874. default:
  1875. return EAI_FAMILY;
  1876. */
  1877. }
  1878. if (serv && (servlen > 0)) {
  1879. if (sa->sa_family == AF_LOCAL) {
  1880. strncpy(serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
  1881. } else { /* AF_INET || AF_INET6 */
  1882. if (!(flags & NI_NUMERICSERV)) {
  1883. struct servent *s;
  1884. s = getservbyport(((const struct sockaddr_in *) sa)->sin_port,
  1885. ((flags & NI_DGRAM) ? "udp" : "tcp"));
  1886. if (s) {
  1887. strncpy(serv, s->s_name, servlen);
  1888. goto DONE;
  1889. }
  1890. }
  1891. snprintf(serv, servlen, "%d",
  1892. ntohs(((const struct sockaddr_in *) sa)->sin_port));
  1893. }
  1894. }
  1895. DONE:
  1896. if (host && (hostlen > 0))
  1897. host[hostlen-1] = 0;
  1898. if (serv && (servlen > 0))
  1899. serv[servlen-1] = 0;
  1900. errno = serrno;
  1901. return 0;
  1902. }
  1903. libc_hidden_def(getnameinfo)
  1904. #endif /* L_getnameinfo */
  1905. #ifdef L_gethostbyname_r
  1906. /* Bug 671 says:
  1907. * "uClibc resolver's gethostbyname does not return the requested name
  1908. * as an alias, but instead returns the canonical name. glibc's
  1909. * gethostbyname has a similar bug where it returns the requested name
  1910. * with the search domain name appended (to make a FQDN) as an alias,
  1911. * but not the original name itself. Both contradict POSIX, which says
  1912. * that the name argument passed to gethostbyname must be in the alias list"
  1913. * This is fixed now, and we differ from glibc:
  1914. *
  1915. * $ ./gethostbyname_uclibc wer.google.com
  1916. * h_name:'c13-ss-2-lb.cnet.com'
  1917. * h_length:4
  1918. * h_addrtype:2 AF_INET
  1919. * alias:'wer.google.com' <===
  1920. * addr: 0x4174efd8 '216.239.116.65'
  1921. *
  1922. * $ ./gethostbyname_glibc wer.google.com
  1923. * h_name:'c13-ss-2-lb.cnet.com'
  1924. * h_length:4
  1925. * h_addrtype:2 AF_INET
  1926. * alias:'wer.google.com.com' <===
  1927. * addr:'216.239.116.65'
  1928. *
  1929. * When examples were run, /etc/resolv.conf contained "search com" line.
  1930. */
  1931. int gethostbyname_r(const char *name,
  1932. struct hostent *result_buf,
  1933. char *buf,
  1934. size_t buflen,
  1935. struct hostent **result,
  1936. int *h_errnop)
  1937. {
  1938. struct in_addr **addr_list;
  1939. char **alias;
  1940. char *alias0;
  1941. unsigned char *packet;
  1942. struct resolv_answer a;
  1943. int i;
  1944. int packet_len;
  1945. int wrong_af = 0;
  1946. *result = NULL;
  1947. if (!name)
  1948. return EINVAL;
  1949. /* do /etc/hosts first */
  1950. {
  1951. int old_errno = errno; /* save the old errno and reset errno */
  1952. __set_errno(0); /* to check for missing /etc/hosts. */
  1953. i = __get_hosts_byname_r(name, AF_INET, result_buf,
  1954. buf, buflen, result, h_errnop);
  1955. if (i == NETDB_SUCCESS) {
  1956. __set_errno(old_errno);
  1957. return i;
  1958. }
  1959. switch (*h_errnop) {
  1960. case HOST_NOT_FOUND:
  1961. wrong_af = (i == TRY_AGAIN);
  1962. case NO_ADDRESS:
  1963. break;
  1964. case NETDB_INTERNAL:
  1965. if (errno == ENOENT) {
  1966. break;
  1967. }
  1968. /* else fall through */
  1969. default:
  1970. return i;
  1971. }
  1972. __set_errno(old_errno);
  1973. }
  1974. DPRINTF("Nothing found in /etc/hosts\n");
  1975. *h_errnop = NETDB_INTERNAL;
  1976. /* prepare future h_aliases[0] */
  1977. i = strlen(name) + 1;
  1978. if ((ssize_t)buflen <= i)
  1979. return ERANGE;
  1980. memcpy(buf, name, i); /* paranoia: name might change */
  1981. alias0 = buf;
  1982. buf += i;
  1983. buflen -= i;
  1984. /* make sure pointer is aligned */
  1985. i = ALIGN_BUFFER_OFFSET(buf);
  1986. buf += i;
  1987. buflen -= i;
  1988. /* Layout in buf:
  1989. * char *alias[2];
  1990. * struct in_addr* addr_list[NN+1];
  1991. * struct in_addr* in[NN];
  1992. */
  1993. alias = (char **)buf;
  1994. buf += sizeof(alias[0]) * 2;
  1995. buflen -= sizeof(alias[0]) * 2;
  1996. addr_list = (struct in_addr **)buf;
  1997. /* buflen may be < 0, must do signed compare */
  1998. if ((ssize_t)buflen < 256)
  1999. return ERANGE;
  2000. /* we store only one "alias" - the name itself */
  2001. alias[0] = alias0;
  2002. alias[1] = NULL;
  2003. /* maybe it is already an address? */
  2004. {
  2005. struct in_addr *in = (struct in_addr *)(buf + sizeof(addr_list[0]) * 2);
  2006. if (inet_aton(name, in)) {
  2007. addr_list[0] = in;
  2008. addr_list[1] = NULL;
  2009. result_buf->h_name = alias0;
  2010. result_buf->h_aliases = alias;
  2011. result_buf->h_addrtype = AF_INET;
  2012. result_buf->h_length = sizeof(struct in_addr);
  2013. result_buf->h_addr_list = (char **) addr_list;
  2014. *result = result_buf;
  2015. *h_errnop = NETDB_SUCCESS;
  2016. return NETDB_SUCCESS;
  2017. }
  2018. }
  2019. /* what if /etc/hosts has it but it's not IPv4?
  2020. * F.e. "::1 localhost6". We don't do DNS query for such hosts -
  2021. * "ping localhost6" should be fast even if DNS server is down! */
  2022. if (wrong_af) {
  2023. *h_errnop = HOST_NOT_FOUND;
  2024. return TRY_AGAIN;
  2025. }
  2026. /* talk to DNS servers */
  2027. a.buf = buf;
  2028. /* take into account that at least one address will be there,
  2029. * we'll need space for one in_addr + two addr_list[] elems */
  2030. a.buflen = buflen - ((sizeof(addr_list[0]) * 2 + sizeof(struct in_addr)));
  2031. a.add_count = 0;
  2032. packet_len = __dns_lookup(name, T_A, &packet, &a);
  2033. if (packet_len < 0) {
  2034. *h_errnop = HOST_NOT_FOUND;
  2035. DPRINTF("__dns_lookup returned < 0\n");
  2036. return TRY_AGAIN;
  2037. }
  2038. if (a.atype == T_A) { /* ADDRESS */
  2039. /* we need space for addr_list[] and one IPv4 address */
  2040. /* + 1 accounting for 1st addr (it's in a.rdata),
  2041. * another + 1 for NULL in last addr_list[]: */
  2042. int need_bytes = sizeof(addr_list[0]) * (a.add_count + 1 + 1)
  2043. /* for 1st addr (it's in a.rdata): */
  2044. + sizeof(struct in_addr);
  2045. /* how many bytes will 2nd and following addresses take? */
  2046. int ips_len = a.add_count * a.rdlength;
  2047. buflen -= (need_bytes + ips_len);
  2048. if ((ssize_t)buflen < 0) {
  2049. DPRINTF("buffer too small for all addresses\n");
  2050. /* *h_errnop = NETDB_INTERNAL; - already is */
  2051. i = ERANGE;
  2052. goto free_and_ret;
  2053. }
  2054. /* if there are additional addresses in buf,
  2055. * move them forward so that they are not destroyed */
  2056. DPRINTF("a.add_count:%d a.rdlength:%d a.rdata:%p\n", a.add_count, a.rdlength, a.rdata);
  2057. memmove(buf + need_bytes, buf, ips_len);
  2058. /* 1st address is in a.rdata, insert it */
  2059. buf += need_bytes - sizeof(struct in_addr);
  2060. memcpy(buf, a.rdata, sizeof(struct in_addr));
  2061. /* fill addr_list[] */
  2062. for (i = 0; i <= a.add_count; i++) {
  2063. addr_list[i] = (struct in_addr*)buf;
  2064. buf += sizeof(struct in_addr);
  2065. }
  2066. addr_list[i] = NULL;
  2067. /* if we have enough space, we can report "better" name
  2068. * (it may contain search domains attached by __dns_lookup,
  2069. * or CNAME of the host if it is different from the name
  2070. * we used to find it) */
  2071. if (a.dotted && buflen > strlen(a.dotted)) {
  2072. strcpy(buf, a.dotted);
  2073. alias0 = buf;
  2074. }
  2075. result_buf->h_name = alias0;
  2076. result_buf->h_aliases = alias;
  2077. result_buf->h_addrtype = AF_INET;
  2078. result_buf->h_length = sizeof(struct in_addr);
  2079. result_buf->h_addr_list = (char **) addr_list;
  2080. *result = result_buf;
  2081. *h_errnop = NETDB_SUCCESS;
  2082. i = NETDB_SUCCESS;
  2083. goto free_and_ret;
  2084. }
  2085. *h_errnop = HOST_NOT_FOUND;
  2086. __set_h_errno(HOST_NOT_FOUND);
  2087. i = TRY_AGAIN;
  2088. free_and_ret:
  2089. free(a.dotted);
  2090. free(packet);
  2091. return i;
  2092. }
  2093. libc_hidden_def(gethostbyname_r)
  2094. #endif /* L_gethostbyname_r */
  2095. #ifdef L_gethostbyname2_r
  2096. int gethostbyname2_r(const char *name,
  2097. int family,
  2098. struct hostent *result_buf,
  2099. char *buf,
  2100. size_t buflen,
  2101. struct hostent **result,
  2102. int *h_errnop)
  2103. {
  2104. #ifndef __UCLIBC_HAS_IPV6__
  2105. return family == (AF_INET)
  2106. ? gethostbyname_r(name, result_buf, buf, buflen, result, h_errnop)
  2107. : HOST_NOT_FOUND;
  2108. #else
  2109. struct in6_addr **addr_list;
  2110. char **alias;
  2111. char *alias0;
  2112. unsigned char *packet;
  2113. struct resolv_answer a;
  2114. int i;
  2115. int packet_len;
  2116. int wrong_af = 0;
  2117. if (family == AF_INET)
  2118. return gethostbyname_r(name, result_buf, buf, buflen, result, h_errnop);
  2119. *result = NULL;
  2120. if (family != AF_INET6)
  2121. return EINVAL;
  2122. if (!name)
  2123. return EINVAL;
  2124. /* do /etc/hosts first */
  2125. {
  2126. int old_errno = errno; /* save the old errno and reset errno */
  2127. __set_errno(0); /* to check for missing /etc/hosts. */
  2128. i = __get_hosts_byname_r(name, AF_INET6 /*family*/, result_buf,
  2129. buf, buflen, result, h_errnop);
  2130. if (i == NETDB_SUCCESS) {
  2131. __set_errno(old_errno);
  2132. return i;
  2133. }
  2134. switch (*h_errnop) {
  2135. case HOST_NOT_FOUND:
  2136. wrong_af = (i == TRY_AGAIN);
  2137. case NO_ADDRESS:
  2138. break;
  2139. case NETDB_INTERNAL:
  2140. if (errno == ENOENT) {
  2141. break;
  2142. }
  2143. /* else fall through */
  2144. default:
  2145. return i;
  2146. }
  2147. __set_errno(old_errno);
  2148. }
  2149. DPRINTF("Nothing found in /etc/hosts\n");
  2150. *h_errnop = NETDB_INTERNAL;
  2151. /* prepare future h_aliases[0] */
  2152. i = strlen(name) + 1;
  2153. if ((ssize_t)buflen <= i)
  2154. return ERANGE;
  2155. memcpy(buf, name, i); /* paranoia: name might change */
  2156. alias0 = buf;
  2157. buf += i;
  2158. buflen -= i;
  2159. /* make sure pointer is aligned */
  2160. i = ALIGN_BUFFER_OFFSET(buf);
  2161. buf += i;
  2162. buflen -= i;
  2163. /* Layout in buf:
  2164. * char *alias[2];
  2165. * struct in6_addr* addr_list[NN+1];
  2166. * struct in6_addr* in[NN];
  2167. */
  2168. alias = (char **)buf;
  2169. buf += sizeof(alias[0]) * 2;
  2170. buflen -= sizeof(alias[0]) * 2;
  2171. addr_list = (struct in6_addr **)buf;
  2172. /* buflen may be < 0, must do signed compare */
  2173. if ((ssize_t)buflen < 256)
  2174. return ERANGE;
  2175. /* we store only one "alias" - the name itself */
  2176. alias[0] = alias0;
  2177. alias[1] = NULL;
  2178. /* maybe it is already an address? */
  2179. {
  2180. struct in6_addr *in = (struct in6_addr *)(buf + sizeof(addr_list[0]) * 2);
  2181. if (inet_pton(AF_INET6, name, in)) {
  2182. addr_list[0] = in;
  2183. addr_list[1] = NULL;
  2184. result_buf->h_name = alias0;
  2185. result_buf->h_aliases = alias;
  2186. result_buf->h_addrtype = AF_INET6;
  2187. result_buf->h_length = sizeof(struct in6_addr);
  2188. result_buf->h_addr_list = (char **) addr_list;
  2189. *result = result_buf;
  2190. *h_errnop = NETDB_SUCCESS;
  2191. return NETDB_SUCCESS;
  2192. }
  2193. }
  2194. /* what if /etc/hosts has it but it's not IPv6?
  2195. * F.e. "127.0.0.1 localhost". We don't do DNS query for such hosts -
  2196. * "ping localhost" should be fast even if DNS server is down! */
  2197. if (wrong_af) {
  2198. *h_errnop = HOST_NOT_FOUND;
  2199. return TRY_AGAIN;
  2200. }
  2201. /* talk to DNS servers */
  2202. a.buf = buf;
  2203. /* take into account that at least one address will be there,
  2204. * we'll need space of one in6_addr + two addr_list[] elems */
  2205. a.buflen = buflen - ((sizeof(addr_list[0]) * 2 + sizeof(struct in6_addr)));
  2206. a.add_count = 0;
  2207. packet_len = __dns_lookup(name, T_AAAA, &packet, &a);
  2208. if (packet_len < 0) {
  2209. *h_errnop = HOST_NOT_FOUND;
  2210. DPRINTF("__dns_lookup returned < 0\n");
  2211. return TRY_AGAIN;
  2212. }
  2213. if (a.atype == T_AAAA) { /* ADDRESS */
  2214. /* we need space for addr_list[] and one IPv6 address */
  2215. /* + 1 accounting for 1st addr (it's in a.rdata),
  2216. * another + 1 for NULL in last addr_list[]: */
  2217. int need_bytes = sizeof(addr_list[0]) * (a.add_count + 1 + 1)
  2218. /* for 1st addr (it's in a.rdata): */
  2219. + sizeof(struct in6_addr);
  2220. /* how many bytes will 2nd and following addresses take? */
  2221. int ips_len = a.add_count * a.rdlength;
  2222. buflen -= (need_bytes + ips_len);
  2223. if ((ssize_t)buflen < 0) {
  2224. DPRINTF("buffer too small for all addresses\n");
  2225. /* *h_errnop = NETDB_INTERNAL; - already is */
  2226. i = ERANGE;
  2227. goto free_and_ret;
  2228. }
  2229. /* if there are additional addresses in buf,
  2230. * move them forward so that they are not destroyed */
  2231. DPRINTF("a.add_count:%d a.rdlength:%d a.rdata:%p\n", a.add_count, a.rdlength, a.rdata);
  2232. memmove(buf + need_bytes, buf, ips_len);
  2233. /* 1st address is in a.rdata, insert it */
  2234. buf += need_bytes - sizeof(struct in6_addr);
  2235. memcpy(buf, a.rdata, sizeof(struct in6_addr));
  2236. /* fill addr_list[] */
  2237. for (i = 0; i <= a.add_count; i++) {
  2238. addr_list[i] = (struct in6_addr*)buf;
  2239. buf += sizeof(struct in6_addr);
  2240. }
  2241. addr_list[i] = NULL;
  2242. /* if we have enough space, we can report "better" name
  2243. * (it may contain search domains attached by __dns_lookup,
  2244. * or CNAME of the host if it is different from the name
  2245. * we used to find it) */
  2246. if (a.dotted && buflen > strlen(a.dotted)) {
  2247. strcpy(buf, a.dotted);
  2248. alias0 = buf;
  2249. }
  2250. result_buf->h_name = alias0;
  2251. result_buf->h_aliases = alias;
  2252. result_buf->h_addrtype = AF_INET6;
  2253. result_buf->h_length = sizeof(struct in6_addr);
  2254. result_buf->h_addr_list = (char **) addr_list;
  2255. *result = result_buf;
  2256. *h_errnop = NETDB_SUCCESS;
  2257. i = NETDB_SUCCESS;
  2258. goto free_and_ret;
  2259. }
  2260. *h_errnop = HOST_NOT_FOUND;
  2261. __set_h_errno(HOST_NOT_FOUND);
  2262. i = TRY_AGAIN;
  2263. free_and_ret:
  2264. free(a.dotted);
  2265. free(packet);
  2266. return i;
  2267. #endif /* __UCLIBC_HAS_IPV6__ */
  2268. }
  2269. libc_hidden_def(gethostbyname2_r)
  2270. #endif /* L_gethostbyname2_r */
  2271. #ifdef L_gethostbyaddr_r
  2272. int gethostbyaddr_r(const void *addr, socklen_t addrlen,
  2273. int type,
  2274. struct hostent *result_buf,
  2275. char *buf, size_t buflen,
  2276. struct hostent **result,
  2277. int *h_errnop)
  2278. {
  2279. struct in_addr *in;
  2280. struct in_addr **addr_list;
  2281. char **alias;
  2282. unsigned char *packet;
  2283. struct resolv_answer a;
  2284. int i;
  2285. int packet_len;
  2286. int nest = 0;
  2287. *result = NULL;
  2288. if (!addr)
  2289. return EINVAL;
  2290. switch (type) {
  2291. #ifdef __UCLIBC_HAS_IPV4__
  2292. case AF_INET:
  2293. if (addrlen != sizeof(struct in_addr))
  2294. return EINVAL;
  2295. break;
  2296. #endif
  2297. #ifdef __UCLIBC_HAS_IPV6__
  2298. case AF_INET6:
  2299. if (addrlen != sizeof(struct in6_addr))
  2300. return EINVAL;
  2301. break;
  2302. #endif
  2303. default:
  2304. return EINVAL;
  2305. }
  2306. /* do /etc/hosts first */
  2307. i = __get_hosts_byaddr_r(addr, addrlen, type, result_buf,
  2308. buf, buflen, result, h_errnop);
  2309. if (i == 0)
  2310. return i;
  2311. switch (*h_errnop) {
  2312. case HOST_NOT_FOUND:
  2313. case NO_ADDRESS:
  2314. break;
  2315. default:
  2316. return i;
  2317. }
  2318. *h_errnop = NETDB_INTERNAL;
  2319. /* make sure pointer is aligned */
  2320. i = ALIGN_BUFFER_OFFSET(buf);
  2321. buf += i;
  2322. buflen -= i;
  2323. /* Layout in buf:
  2324. * char *alias[ALIAS_DIM];
  2325. * struct in[6]_addr* addr_list[2];
  2326. * struct in[6]_addr in;
  2327. * char scratch_buffer[256+];
  2328. */
  2329. #define in6 ((struct in6_addr *)in)
  2330. alias = (char **)buf;
  2331. addr_list = (struct in_addr**)buf;
  2332. buf += sizeof(*addr_list) * 2;
  2333. buflen -= sizeof(*addr_list) * 2;
  2334. in = (struct in_addr*)buf;
  2335. #ifndef __UCLIBC_HAS_IPV6__
  2336. buf += sizeof(*in);
  2337. buflen -= sizeof(*in);
  2338. if (addrlen > sizeof(*in))
  2339. return ERANGE;
  2340. #else
  2341. buf += sizeof(*in6);
  2342. buflen -= sizeof(*in6);
  2343. if (addrlen > sizeof(*in6))
  2344. return ERANGE;
  2345. #endif
  2346. if ((ssize_t)buflen < 256)
  2347. return ERANGE;
  2348. alias[0] = buf;
  2349. alias[1] = NULL;
  2350. addr_list[0] = in;
  2351. addr_list[1] = NULL;
  2352. memcpy(in, addr, addrlen);
  2353. if (0) /* nothing */;
  2354. #ifdef __UCLIBC_HAS_IPV4__
  2355. else IF_HAS_BOTH(if (type == AF_INET)) {
  2356. unsigned char *tp = (unsigned char *)addr;
  2357. sprintf(buf, "%u.%u.%u.%u.in-addr.arpa",
  2358. tp[3], tp[2], tp[1], tp[0]);
  2359. }
  2360. #endif
  2361. #ifdef __UCLIBC_HAS_IPV6__
  2362. else {
  2363. char *dst = buf;
  2364. unsigned char *tp = (unsigned char *)addr + addrlen - 1;
  2365. do {
  2366. dst += sprintf(dst, "%x.%x.", tp[0] & 0xf, tp[0] >> 4);
  2367. tp--;
  2368. } while (tp >= (unsigned char *)addr);
  2369. strcpy(dst, "ip6.arpa");
  2370. }
  2371. #endif
  2372. memset(&a, '\0', sizeof(a));
  2373. for (;;) {
  2374. /* Hmm why we memset(a) to zeros only once? */
  2375. packet_len = __dns_lookup(buf, T_PTR, &packet, &a);
  2376. if (packet_len < 0) {
  2377. *h_errnop = HOST_NOT_FOUND;
  2378. return TRY_AGAIN;
  2379. }
  2380. strncpy(buf, a.dotted, buflen);
  2381. free(a.dotted);
  2382. if (a.atype != T_CNAME)
  2383. break;
  2384. DPRINTF("Got a CNAME in gethostbyaddr()\n");
  2385. if (++nest > MAX_RECURSE) {
  2386. *h_errnop = NO_RECOVERY;
  2387. return -1;
  2388. }
  2389. /* Decode CNAME into buf, feed it to __dns_lookup() again */
  2390. i = __decode_dotted(packet, a.rdoffset, packet_len, buf, buflen);
  2391. free(packet);
  2392. if (i < 0 || __hnbad(buf)) {
  2393. *h_errnop = NO_RECOVERY;
  2394. return -1;
  2395. }
  2396. }
  2397. if (a.atype == T_PTR) { /* ADDRESS */
  2398. i = __decode_dotted(packet, a.rdoffset, packet_len, buf, buflen);
  2399. free(packet);
  2400. if (__hnbad(buf)) {
  2401. *h_errnop = NO_RECOVERY;
  2402. return -1;
  2403. }
  2404. result_buf->h_name = buf;
  2405. result_buf->h_addrtype = type;
  2406. result_buf->h_length = addrlen;
  2407. result_buf->h_addr_list = (char **) addr_list;
  2408. result_buf->h_aliases = alias;
  2409. *result = result_buf;
  2410. *h_errnop = NETDB_SUCCESS;
  2411. return NETDB_SUCCESS;
  2412. }
  2413. free(packet);
  2414. *h_errnop = NO_ADDRESS;
  2415. return TRY_AGAIN;
  2416. #undef in6
  2417. }
  2418. libc_hidden_def(gethostbyaddr_r)
  2419. #endif /* L_gethostbyaddr_r */
  2420. #ifdef L_gethostent_r
  2421. __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
  2422. static parser_t *hostp = NULL;
  2423. static smallint host_stayopen;
  2424. void endhostent_unlocked(void)
  2425. {
  2426. if (hostp) {
  2427. config_close(hostp);
  2428. hostp = NULL;
  2429. }
  2430. host_stayopen = 0;
  2431. }
  2432. void endhostent(void)
  2433. {
  2434. __UCLIBC_MUTEX_LOCK(mylock);
  2435. endhostent_unlocked();
  2436. __UCLIBC_MUTEX_UNLOCK(mylock);
  2437. }
  2438. void sethostent(int stay_open)
  2439. {
  2440. __UCLIBC_MUTEX_LOCK(mylock);
  2441. if (stay_open)
  2442. host_stayopen = 1;
  2443. __UCLIBC_MUTEX_UNLOCK(mylock);
  2444. }
  2445. int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen,
  2446. struct hostent **result, int *h_errnop)
  2447. {
  2448. int ret;
  2449. __UCLIBC_MUTEX_LOCK(mylock);
  2450. if (hostp == NULL) {
  2451. hostp = __open_etc_hosts();
  2452. if (hostp == NULL) {
  2453. *result = NULL;
  2454. ret = TRY_AGAIN;
  2455. goto DONE;
  2456. }
  2457. }
  2458. ret = __read_etc_hosts_r(hostp, NULL, AF_INET, GETHOSTENT,
  2459. result_buf, buf, buflen, result, h_errnop);
  2460. if (!host_stayopen)
  2461. endhostent_unlocked();
  2462. DONE:
  2463. __UCLIBC_MUTEX_UNLOCK(mylock);
  2464. return ret;
  2465. }
  2466. libc_hidden_def(gethostent_r)
  2467. #endif /* L_gethostent_r */
  2468. #ifndef __UCLIBC_HAS_IPV6__
  2469. #define GETXX_BUFSZ (sizeof(struct in_addr) + sizeof(struct in_addr *) * 2 + \
  2470. /*sizeof(char *)*ALIAS_DIM */+ 384/*namebuffer*/ + 32/* margin */)
  2471. #else
  2472. #define GETXX_BUFSZ (sizeof(struct in6_addr) + sizeof(struct in6_addr *) * 2 + \
  2473. /*sizeof(char *)*ALIAS_DIM */+ 384/*namebuffer*/ + 32/* margin */)
  2474. #endif /* __UCLIBC_HAS_IPV6__ */
  2475. #define __INIT_GETXX_BUF(sz) \
  2476. if (buf == NULL) \
  2477. buf = (char *)__uc_malloc((sz));
  2478. #ifdef L_gethostent
  2479. struct hostent *gethostent(void)
  2480. {
  2481. static struct hostent hoste;
  2482. static char *buf = NULL;
  2483. struct hostent *host = NULL;
  2484. #ifndef __UCLIBC_HAS_IPV6__
  2485. #define HOSTENT_BUFSZ (sizeof(struct in_addr) + sizeof(struct in_addr *) * 2 + \
  2486. sizeof(char *)*ALIAS_DIM + BUFSZ /*namebuffer*/ + 2 /* margin */)
  2487. #else
  2488. #define HOSTENT_BUFSZ (sizeof(struct in6_addr) + sizeof(struct in6_addr *) * 2 + \
  2489. sizeof(char *)*ALIAS_DIM + BUFSZ /*namebuffer*/ + 2 /* margin */)
  2490. #endif /* __UCLIBC_HAS_IPV6__ */
  2491. __INIT_GETXX_BUF(HOSTENT_BUFSZ);
  2492. gethostent_r(&hoste, buf, HOSTENT_BUFSZ, &host, &h_errno);
  2493. return host;
  2494. }
  2495. #undef HOSTENT_BUFSZ
  2496. #endif /* L_gethostent */
  2497. #ifdef L_gethostbyname2
  2498. struct hostent *gethostbyname2(const char *name, int family)
  2499. {
  2500. static struct hostent hoste;
  2501. static char *buf = NULL;
  2502. struct hostent *hp;
  2503. __INIT_GETXX_BUF(GETXX_BUFSZ);
  2504. #ifndef __UCLIBC_HAS_IPV6__
  2505. if (family != AF_INET)
  2506. return (struct hostent*)NULL;
  2507. gethostbyname_r(name, &hoste, buf, GETXX_BUFSZ, &hp, &h_errno);
  2508. #else
  2509. gethostbyname2_r(name, family, &hoste, buf, GETXX_BUFSZ, &hp, &h_errno);
  2510. #endif /* __UCLIBC_HAS_IPV6__ */
  2511. return hp;
  2512. }
  2513. libc_hidden_def(gethostbyname2)
  2514. #endif /* L_gethostbyname2 */
  2515. #ifdef L_gethostbyname
  2516. struct hostent *gethostbyname(const char *name)
  2517. {
  2518. return gethostbyname2(name, AF_INET);
  2519. }
  2520. libc_hidden_def(gethostbyname)
  2521. #endif /* L_gethostbyname */
  2522. #ifdef L_gethostbyaddr
  2523. struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type)
  2524. {
  2525. static struct hostent hoste;
  2526. static char *buf = NULL;
  2527. struct hostent *hp;
  2528. __INIT_GETXX_BUF(GETXX_BUFSZ);
  2529. gethostbyaddr_r(addr, len, type, &hoste, buf, GETXX_BUFSZ, &hp, &h_errno);
  2530. return hp;
  2531. }
  2532. libc_hidden_def(gethostbyaddr)
  2533. #endif /* L_gethostbyaddr */
  2534. #ifdef L_res_comp
  2535. /*
  2536. * Expand compressed domain name 'comp_dn' to full domain name.
  2537. * 'msg' is a pointer to the begining of the message,
  2538. * 'eomorig' points to the first location after the message,
  2539. * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
  2540. * Return size of compressed name or -1 if there was an error.
  2541. */
  2542. int weak_function dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
  2543. char *dst, int dstsiz)
  2544. {
  2545. int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
  2546. if (n > 0 && dst[0] == '.')
  2547. dst[0] = '\0';
  2548. return n;
  2549. }
  2550. libc_hidden_weak(dn_expand)
  2551. /*
  2552. * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
  2553. * Return the size of the compressed name or -1.
  2554. * 'length' is the size of the array pointed to by 'comp_dn'.
  2555. */
  2556. int weak_function
  2557. dn_comp(const char *src, u_char *dst, int dstsiz,
  2558. u_char **dnptrs, u_char **lastdnptr)
  2559. {
  2560. return ns_name_compress(src, dst, (size_t) dstsiz,
  2561. (const u_char **) dnptrs,
  2562. (const u_char **) lastdnptr);
  2563. }
  2564. libc_hidden_weak(dn_comp)
  2565. #endif /* L_res_comp */
  2566. #ifdef L_ns_name
  2567. /* Thinking in noninternationalized USASCII (per the DNS spec),
  2568. * is this character visible and not a space when printed ?
  2569. */
  2570. static int printable(int ch)
  2571. {
  2572. return (ch > 0x20 && ch < 0x7f);
  2573. }
  2574. /* Thinking in noninternationalized USASCII (per the DNS spec),
  2575. * is this characted special ("in need of quoting") ?
  2576. */
  2577. static int special(int ch)
  2578. {
  2579. switch (ch) {
  2580. case 0x22: /* '"' */
  2581. case 0x2E: /* '.' */
  2582. case 0x3B: /* ';' */
  2583. case 0x5C: /* '\\' */
  2584. /* Special modifiers in zone files. */
  2585. case 0x40: /* '@' */
  2586. case 0x24: /* '$' */
  2587. return 1;
  2588. default:
  2589. return 0;
  2590. }
  2591. }
  2592. /*
  2593. * ns_name_uncompress(msg, eom, src, dst, dstsiz)
  2594. * Expand compressed domain name to presentation format.
  2595. * return:
  2596. * Number of bytes read out of `src', or -1 (with errno set).
  2597. * note:
  2598. * Root domain returns as "." not "".
  2599. */
  2600. int weak_function ns_name_uncompress(const u_char *msg, const u_char *eom,
  2601. const u_char *src, char *dst, size_t dstsiz)
  2602. {
  2603. u_char tmp[NS_MAXCDNAME];
  2604. int n;
  2605. n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp);
  2606. if (n == -1)
  2607. return -1;
  2608. if (ns_name_ntop(tmp, dst, dstsiz) == -1)
  2609. return -1;
  2610. return n;
  2611. }
  2612. libc_hidden_weak(ns_name_uncompress)
  2613. /*
  2614. * ns_name_ntop(src, dst, dstsiz)
  2615. * Convert an encoded domain name to printable ascii as per RFC1035.
  2616. * return:
  2617. * Number of bytes written to buffer, or -1 (with errno set)
  2618. * notes:
  2619. * The root is returned as "."
  2620. * All other domains are returned in non absolute form
  2621. */
  2622. int weak_function ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
  2623. {
  2624. const u_char *cp;
  2625. char *dn, *eom;
  2626. u_char c;
  2627. u_int n;
  2628. cp = src;
  2629. dn = dst;
  2630. eom = dst + dstsiz;
  2631. while ((n = *cp++) != 0) {
  2632. if ((n & NS_CMPRSFLGS) != 0) {
  2633. /* Some kind of compression pointer. */
  2634. __set_errno(EMSGSIZE);
  2635. return -1;
  2636. }
  2637. if (dn != dst) {
  2638. if (dn >= eom) {
  2639. __set_errno(EMSGSIZE);
  2640. return -1;
  2641. }
  2642. *dn++ = '.';
  2643. }
  2644. if (dn + n >= eom) {
  2645. __set_errno(EMSGSIZE);
  2646. return -1;
  2647. }
  2648. for (; n > 0; n--) {
  2649. c = *cp++;
  2650. if (special(c)) {
  2651. if (dn + 1 >= eom) {
  2652. __set_errno(EMSGSIZE);
  2653. return -1;
  2654. }
  2655. *dn++ = '\\';
  2656. *dn++ = (char)c;
  2657. } else if (!printable(c)) {
  2658. if (dn + 3 >= eom) {
  2659. __set_errno(EMSGSIZE);
  2660. return -1;
  2661. }
  2662. *dn++ = '\\';
  2663. *dn++ = "0123456789"[c / 100];
  2664. c = c % 100;
  2665. *dn++ = "0123456789"[c / 10];
  2666. *dn++ = "0123456789"[c % 10];
  2667. } else {
  2668. if (dn >= eom) {
  2669. __set_errno(EMSGSIZE);
  2670. return -1;
  2671. }
  2672. *dn++ = (char)c;
  2673. }
  2674. }
  2675. }
  2676. if (dn == dst) {
  2677. if (dn >= eom) {
  2678. __set_errno(EMSGSIZE);
  2679. return -1;
  2680. }
  2681. *dn++ = '.';
  2682. }
  2683. if (dn >= eom) {
  2684. __set_errno(EMSGSIZE);
  2685. return -1;
  2686. }
  2687. *dn++ = '\0';
  2688. return (dn - dst);
  2689. }
  2690. libc_hidden_weak(ns_name_ntop)
  2691. static int encode_bitstring(const char **bp, const char *end,
  2692. unsigned char **labelp,
  2693. unsigned char ** dst,
  2694. unsigned const char *eom)
  2695. {
  2696. int afterslash = 0;
  2697. const char *cp = *bp;
  2698. unsigned char *tp;
  2699. const char *beg_blen;
  2700. int value = 0, count = 0, tbcount = 0, blen = 0;
  2701. beg_blen = NULL;
  2702. /* a bitstring must contain at least 2 characters */
  2703. if (end - cp < 2)
  2704. return EINVAL;
  2705. /* XXX: currently, only hex strings are supported */
  2706. if (*cp++ != 'x')
  2707. return EINVAL;
  2708. if (!isxdigit((unsigned char) *cp)) /*%< reject '\[x/BLEN]' */
  2709. return EINVAL;
  2710. for (tp = *dst + 1; cp < end && tp < eom; cp++) {
  2711. unsigned char c = *cp;
  2712. switch (c) {
  2713. case ']': /*%< end of the bitstring */
  2714. if (afterslash) {
  2715. char *end_blen;
  2716. if (beg_blen == NULL)
  2717. return EINVAL;
  2718. blen = (int)strtol(beg_blen, &end_blen, 10);
  2719. if (*end_blen != ']')
  2720. return EINVAL;
  2721. }
  2722. if (count)
  2723. *tp++ = ((value << 4) & 0xff);
  2724. cp++; /*%< skip ']' */
  2725. goto done;
  2726. case '/':
  2727. afterslash = 1;
  2728. break;
  2729. default:
  2730. if (afterslash) {
  2731. if (!__isdigit_char(c))
  2732. return EINVAL;
  2733. if (beg_blen == NULL) {
  2734. if (c == '0') {
  2735. /* blen never begings with 0 */
  2736. return EINVAL;
  2737. }
  2738. beg_blen = cp;
  2739. }
  2740. } else {
  2741. if (!__isdigit_char(c)) {
  2742. c = c | 0x20; /* lowercase */
  2743. c = c - 'a';
  2744. if (c > 5) /* not a-f? */
  2745. return EINVAL;
  2746. c += 10 + '0';
  2747. }
  2748. value <<= 4;
  2749. value += (c - '0');
  2750. count += 4;
  2751. tbcount += 4;
  2752. if (tbcount > 256)
  2753. return EINVAL;
  2754. if (count == 8) {
  2755. *tp++ = value;
  2756. count = 0;
  2757. }
  2758. }
  2759. break;
  2760. }
  2761. }
  2762. done:
  2763. if (cp >= end || tp >= eom)
  2764. return EMSGSIZE;
  2765. /*
  2766. * bit length validation:
  2767. * If a <length> is present, the number of digits in the <bit-data>
  2768. * MUST be just sufficient to contain the number of bits specified
  2769. * by the <length>. If there are insignificant bits in a final
  2770. * hexadecimal or octal digit, they MUST be zero.
  2771. * RFC2673, Section 3.2.
  2772. */
  2773. if (blen > 0) {
  2774. int traillen;
  2775. if (((blen + 3) & ~3) != tbcount)
  2776. return EINVAL;
  2777. traillen = tbcount - blen; /*%< between 0 and 3 */
  2778. if (((value << (8 - traillen)) & 0xff) != 0)
  2779. return EINVAL;
  2780. }
  2781. else
  2782. blen = tbcount;
  2783. if (blen == 256)
  2784. blen = 0;
  2785. /* encode the type and the significant bit fields */
  2786. **labelp = DNS_LABELTYPE_BITSTRING;
  2787. **dst = blen;
  2788. *bp = cp;
  2789. *dst = tp;
  2790. return 0;
  2791. }
  2792. int weak_function ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
  2793. {
  2794. static const char digits[] = "0123456789";
  2795. u_char *label, *bp, *eom;
  2796. int c, n, escaped, e = 0;
  2797. char *cp;
  2798. escaped = 0;
  2799. bp = dst;
  2800. eom = dst + dstsiz;
  2801. label = bp++;
  2802. while ((c = *src++) != 0) {
  2803. if (escaped) {
  2804. if (c == '[') { /*%< start a bit string label */
  2805. cp = strchr(src, ']');
  2806. if (cp == NULL) {
  2807. errno = EINVAL; /*%< ??? */
  2808. return -1;
  2809. }
  2810. e = encode_bitstring(&src, cp + 2,
  2811. &label, &bp, eom);
  2812. if (e != 0) {
  2813. errno = e;
  2814. return -1;
  2815. }
  2816. escaped = 0;
  2817. label = bp++;
  2818. c = *src++;
  2819. if (c == '\0')
  2820. goto done;
  2821. if (c != '.') {
  2822. errno = EINVAL;
  2823. return -1;
  2824. }
  2825. continue;
  2826. }
  2827. cp = strchr(digits, c);
  2828. if (cp != NULL) {
  2829. n = (cp - digits) * 100;
  2830. c = *src++;
  2831. if (c == '\0')
  2832. goto ret_EMSGSIZE;
  2833. cp = strchr(digits, c);
  2834. if (cp == NULL)
  2835. goto ret_EMSGSIZE;
  2836. n += (cp - digits) * 10;
  2837. c = *src++;
  2838. if (c == '\0')
  2839. goto ret_EMSGSIZE;
  2840. cp = strchr(digits, c);
  2841. if (cp == NULL)
  2842. goto ret_EMSGSIZE;
  2843. n += (cp - digits);
  2844. if (n > 255)
  2845. goto ret_EMSGSIZE;
  2846. c = n;
  2847. }
  2848. escaped = 0;
  2849. } else if (c == '\\') {
  2850. escaped = 1;
  2851. continue;
  2852. } else if (c == '.') {
  2853. c = (bp - label - 1);
  2854. if ((c & NS_CMPRSFLGS) != 0) { /*%< Label too big. */
  2855. goto ret_EMSGSIZE;
  2856. }
  2857. if (label >= eom) {
  2858. goto ret_EMSGSIZE;
  2859. }
  2860. *label = c;
  2861. /* Fully qualified ? */
  2862. if (*src == '\0') {
  2863. if (c != 0) {
  2864. if (bp >= eom) {
  2865. goto ret_EMSGSIZE;
  2866. }
  2867. *bp++ = '\0';
  2868. }
  2869. if ((bp - dst) > MAXCDNAME) {
  2870. goto ret_EMSGSIZE;
  2871. }
  2872. return 1;
  2873. }
  2874. if (c == 0 || *src == '.') {
  2875. goto ret_EMSGSIZE;
  2876. }
  2877. label = bp++;
  2878. continue;
  2879. }
  2880. if (bp >= eom) {
  2881. goto ret_EMSGSIZE;
  2882. }
  2883. *bp++ = (u_char)c;
  2884. }
  2885. c = (bp - label - 1);
  2886. if ((c & NS_CMPRSFLGS) != 0) { /*%< Label too big. */
  2887. goto ret_EMSGSIZE;
  2888. }
  2889. done:
  2890. if (label >= eom) {
  2891. goto ret_EMSGSIZE;
  2892. }
  2893. *label = c;
  2894. if (c != 0) {
  2895. if (bp >= eom) {
  2896. goto ret_EMSGSIZE;
  2897. }
  2898. *bp++ = 0;
  2899. }
  2900. if ((bp - dst) > MAXCDNAME) { /*%< src too big */
  2901. goto ret_EMSGSIZE;
  2902. }
  2903. return 0;
  2904. ret_EMSGSIZE:
  2905. errno = EMSGSIZE;
  2906. return -1;
  2907. }
  2908. libc_hidden_weak(ns_name_pton)
  2909. /*
  2910. * __hnbad(dotted)
  2911. * Check whether a name is valid enough for DNS. The rules, as
  2912. * laid down by glibc, are:
  2913. * - printable input string
  2914. * - converts to label notation
  2915. * - each label only contains [0-9a-zA-Z_-], up to 63 octets
  2916. * - first label doesn’t begin with ‘-’
  2917. * This both is weaker than Unix hostnames (e.g. it allows
  2918. * underscores and leading/trailing hyphen-minus) and stronger
  2919. * than general (e.g. a leading “*.” is valid sometimes), take care.
  2920. * return:
  2921. * 0 if the name is ok
  2922. */
  2923. int weak_function __hnbad(const char *dotted)
  2924. {
  2925. unsigned char c, n, *cp;
  2926. unsigned char buf[NS_MAXCDNAME];
  2927. cp = (unsigned char *)dotted;
  2928. while ((c = *cp++))
  2929. if (c < 0x21 || c > 0x7E)
  2930. return (1);
  2931. if (ns_name_pton(dotted, buf, sizeof(buf)) < 0)
  2932. return (2);
  2933. if (buf[0] > 0 && buf[1] == '-')
  2934. return (3);
  2935. cp = buf;
  2936. while ((n = *cp++)) {
  2937. if (n > 63)
  2938. return (4);
  2939. while (n--) {
  2940. c = *cp++;
  2941. if (c < '-' ||
  2942. (c > '-' && c < '0') ||
  2943. (c > '9' && c < 'A') ||
  2944. (c > 'Z' && c < '_') ||
  2945. (c > '_' && c < 'a') ||
  2946. c > 'z')
  2947. return (5);
  2948. }
  2949. }
  2950. return (0);
  2951. }
  2952. /*
  2953. * ns_name_unpack(msg, eom, src, dst, dstsiz)
  2954. * Unpack a domain name from a message, source may be compressed.
  2955. * return:
  2956. * -1 if it fails, or consumed octets if it succeeds.
  2957. */
  2958. int weak_function ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
  2959. u_char *dst, size_t dstsiz)
  2960. {
  2961. const u_char *srcp, *dstlim;
  2962. u_char *dstp;
  2963. int n, len, checked;
  2964. len = -1;
  2965. checked = 0;
  2966. dstp = dst;
  2967. srcp = src;
  2968. dstlim = dst + dstsiz;
  2969. if (srcp < msg || srcp >= eom) {
  2970. __set_errno(EMSGSIZE);
  2971. return -1;
  2972. }
  2973. /* Fetch next label in domain name. */
  2974. while ((n = *srcp++) != 0) {
  2975. /* Check for indirection. */
  2976. switch (n & NS_CMPRSFLGS) {
  2977. case 0:
  2978. /* Limit checks. */
  2979. if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
  2980. __set_errno(EMSGSIZE);
  2981. return -1;
  2982. }
  2983. checked += n + 1;
  2984. *dstp++ = n;
  2985. memcpy(dstp, srcp, n);
  2986. dstp += n;
  2987. srcp += n;
  2988. break;
  2989. case NS_CMPRSFLGS:
  2990. if (srcp >= eom) {
  2991. __set_errno(EMSGSIZE);
  2992. return -1;
  2993. }
  2994. if (len < 0)
  2995. len = srcp - src + 1;
  2996. srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
  2997. if (srcp < msg || srcp >= eom) { /* Out of range. */
  2998. __set_errno(EMSGSIZE);
  2999. return -1;
  3000. }
  3001. checked += 2;
  3002. /*
  3003. * Check for loops in the compressed name;
  3004. * if we've looked at the whole message,
  3005. * there must be a loop.
  3006. */
  3007. if (checked >= eom - msg) {
  3008. __set_errno(EMSGSIZE);
  3009. return -1;
  3010. }
  3011. break;
  3012. default:
  3013. __set_errno(EMSGSIZE);
  3014. return -1; /* flag error */
  3015. }
  3016. }
  3017. *dstp = '\0';
  3018. if (len < 0)
  3019. len = srcp - src;
  3020. return len;
  3021. }
  3022. libc_hidden_weak(ns_name_unpack)
  3023. static int labellen(const unsigned char *lp)
  3024. {
  3025. unsigned bitlen;
  3026. unsigned char l = *lp;
  3027. if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
  3028. /* should be avoided by the caller */
  3029. return -1;
  3030. }
  3031. if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {
  3032. if (l == DNS_LABELTYPE_BITSTRING) {
  3033. bitlen = lp[1];
  3034. if (bitlen == 0)
  3035. bitlen = 256;
  3036. return ((bitlen + 7 ) / 8 + 1);
  3037. }
  3038. return -1; /*%< unknwon ELT */
  3039. }
  3040. return l;
  3041. }
  3042. static int mklower(int ch)
  3043. {
  3044. if (ch >= 0x41 && ch <= 0x5A)
  3045. return (ch + 0x20);
  3046. return ch;
  3047. }
  3048. static int dn_find(const unsigned char *domain,
  3049. const unsigned char *msg,
  3050. const unsigned char * const *dnptrs,
  3051. const unsigned char * const *lastdnptr)
  3052. {
  3053. const unsigned char *dn, *cp, *sp;
  3054. const unsigned char * const *cpp;
  3055. u_int n;
  3056. for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
  3057. sp = *cpp;
  3058. /*
  3059. * terminate search on:
  3060. * root label
  3061. * compression pointer
  3062. * unusable offset
  3063. */
  3064. while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
  3065. (sp - msg) < 0x4000) {
  3066. dn = domain;
  3067. cp = sp;
  3068. while ((n = *cp++) != 0) {
  3069. /*
  3070. * check for indirection
  3071. */
  3072. switch (n & NS_CMPRSFLGS) {
  3073. case 0: /*%< normal case, n == len */
  3074. n = labellen(cp - 1); /*%< XXX */
  3075. if (n != *dn++)
  3076. goto next;
  3077. for (; n > 0; n--)
  3078. if (mklower(*dn++) !=
  3079. mklower(*cp++))
  3080. goto next;
  3081. /* Is next root for both ? */
  3082. if (*dn == '\0' && *cp == '\0')
  3083. return (sp - msg);
  3084. if (*dn)
  3085. continue;
  3086. goto next;
  3087. case NS_CMPRSFLGS: /*%< indirection */
  3088. cp = msg + (((n & 0x3f) << 8) | *cp);
  3089. break;
  3090. default: /*%< illegal type */
  3091. errno = EMSGSIZE;
  3092. return -1;
  3093. }
  3094. }
  3095. next:
  3096. sp += *sp + 1;
  3097. }
  3098. }
  3099. errno = ENOENT;
  3100. return -1;
  3101. }
  3102. int weak_function ns_name_pack(const unsigned char *src,
  3103. unsigned char *dst, int dstsiz,
  3104. const unsigned char **dnptrs,
  3105. const unsigned char **lastdnptr)
  3106. {
  3107. unsigned char *dstp;
  3108. const unsigned char **cpp, **lpp, *eob, *msg;
  3109. const unsigned char *srcp;
  3110. int n, l, first = 1;
  3111. srcp = src;
  3112. dstp = dst;
  3113. eob = dstp + dstsiz;
  3114. lpp = cpp = NULL;
  3115. if (dnptrs != NULL) {
  3116. msg = *dnptrs++;
  3117. if (msg != NULL) {
  3118. for (cpp = dnptrs; *cpp != NULL; cpp++)
  3119. continue;
  3120. lpp = cpp; /*%< end of list to search */
  3121. }
  3122. } else {
  3123. msg = NULL;
  3124. }
  3125. /* make sure the domain we are about to add is legal */
  3126. l = 0;
  3127. do {
  3128. int l0;
  3129. n = *srcp;
  3130. if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
  3131. errno = EMSGSIZE;
  3132. return -1;
  3133. }
  3134. l0 = labellen(srcp);
  3135. if (l0 < 0) {
  3136. errno = EINVAL;
  3137. return -1;
  3138. }
  3139. l += l0 + 1;
  3140. if (l > MAXCDNAME) {
  3141. errno = EMSGSIZE;
  3142. return -1;
  3143. }
  3144. srcp += l0 + 1;
  3145. } while (n != 0);
  3146. /* from here on we need to reset compression pointer array on error */
  3147. srcp = src;
  3148. do {
  3149. /* Look to see if we can use pointers. */
  3150. n = *srcp;
  3151. if (n != 0 && msg != NULL) {
  3152. l = dn_find(srcp, msg, (const unsigned char * const *) dnptrs,
  3153. (const unsigned char * const *) lpp);
  3154. if (l >= 0) {
  3155. if (dstp + 1 >= eob) {
  3156. goto cleanup;
  3157. }
  3158. *dstp++ = ((u_int32_t)l >> 8) | NS_CMPRSFLGS;
  3159. *dstp++ = l % 256;
  3160. return (dstp - dst);
  3161. }
  3162. /* Not found, save it. */
  3163. if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
  3164. (dstp - msg) < 0x4000 && first) {
  3165. *cpp++ = dstp;
  3166. *cpp = NULL;
  3167. first = 0;
  3168. }
  3169. }
  3170. /* copy label to buffer */
  3171. if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
  3172. /* Should not happen. */
  3173. goto cleanup;
  3174. }
  3175. n = labellen(srcp);
  3176. if (dstp + 1 + n >= eob) {
  3177. goto cleanup;
  3178. }
  3179. memcpy(dstp, srcp, (size_t)(n + 1));
  3180. srcp += n + 1;
  3181. dstp += n + 1;
  3182. } while (n != 0);
  3183. if (dstp > eob) {
  3184. cleanup:
  3185. if (msg != NULL)
  3186. *lpp = NULL;
  3187. errno = EMSGSIZE;
  3188. return -1;
  3189. }
  3190. return dstp - dst;
  3191. }
  3192. libc_hidden_weak(ns_name_pack)
  3193. int weak_function ns_name_compress(const char *src,
  3194. unsigned char *dst, size_t dstsiz,
  3195. const unsigned char **dnptrs,
  3196. const unsigned char **lastdnptr)
  3197. {
  3198. unsigned char tmp[NS_MAXCDNAME];
  3199. if (ns_name_pton(src, tmp, sizeof(tmp)) == -1)
  3200. return -1;
  3201. return ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr);
  3202. }
  3203. libc_hidden_weak(ns_name_compress)
  3204. int weak_function ns_name_skip(const unsigned char **ptrptr,
  3205. const unsigned char *eom)
  3206. {
  3207. const unsigned char *cp;
  3208. u_int n;
  3209. int l;
  3210. cp = *ptrptr;
  3211. while (cp < eom && (n = *cp++) != 0) {
  3212. /* Check for indirection. */
  3213. switch (n & NS_CMPRSFLGS) {
  3214. case 0: /*%< normal case, n == len */
  3215. cp += n;
  3216. continue;
  3217. case NS_TYPE_ELT: /*%< EDNS0 extended label */
  3218. l = labellen(cp - 1);
  3219. if (l < 0) {
  3220. errno = EMSGSIZE; /*%< XXX */
  3221. return -1;
  3222. }
  3223. cp += l;
  3224. continue;
  3225. case NS_CMPRSFLGS: /*%< indirection */
  3226. cp++;
  3227. break;
  3228. default: /*%< illegal type */
  3229. errno = EMSGSIZE;
  3230. return -1;
  3231. }
  3232. break;
  3233. }
  3234. if (cp > eom) {
  3235. errno = EMSGSIZE;
  3236. return -1;
  3237. }
  3238. *ptrptr = cp;
  3239. return 0;
  3240. }
  3241. libc_hidden_weak(ns_name_skip)
  3242. int weak_function dn_skipname(const unsigned char *ptr, const unsigned char *eom)
  3243. {
  3244. const unsigned char *saveptr = ptr;
  3245. if (ns_name_skip(&ptr, eom) == -1)
  3246. return -1;
  3247. return ptr - saveptr;
  3248. }
  3249. libc_hidden_weak(dn_skipname)
  3250. #endif /* L_ns_name */
  3251. #ifdef L_res_init
  3252. /* Will be called under __resolv_lock. */
  3253. static void res_sync_func(void)
  3254. {
  3255. struct __res_state *rp = __res_state();
  3256. int n;
  3257. /* If we didn't get malloc failure earlier... */
  3258. if (__nameserver != (void*) &__local_nameserver) {
  3259. /* TODO:
  3260. * if (__nameservers < rp->nscount) - try to grow __nameserver[]?
  3261. */
  3262. #ifdef __UCLIBC_HAS_IPV6__
  3263. if (__nameservers > rp->_u._ext.nscount)
  3264. __nameservers = rp->_u._ext.nscount;
  3265. n = __nameservers;
  3266. while (--n >= 0)
  3267. __nameserver[n].sa6 = *rp->_u._ext.nsaddrs[n]; /* struct copy */
  3268. #else /* IPv4 only */
  3269. if (__nameservers > rp->nscount)
  3270. __nameservers = rp->nscount;
  3271. n = __nameservers;
  3272. while (--n >= 0)
  3273. __nameserver[n].sa4 = rp->nsaddr_list[n]; /* struct copy */
  3274. #endif
  3275. }
  3276. __resolv_timeout = rp->retrans ? : RES_TIMEOUT;
  3277. __resolv_attempts = rp->retry ? : RES_DFLRETRY;
  3278. /* Extend and comment what program is known
  3279. * to use which _res.XXX member(s).
  3280. __resolv_opts = rp->options;
  3281. ...
  3282. */
  3283. }
  3284. /* has to be called under __resolv_lock */
  3285. static int
  3286. __res_vinit(res_state rp, int preinit)
  3287. {
  3288. int i, n, options, retrans, retry, ndots;
  3289. #ifdef __UCLIBC_HAS_IPV6__
  3290. int m = 0;
  3291. #endif
  3292. __close_nameservers();
  3293. __open_nameservers();
  3294. if (preinit) {
  3295. options = rp->options;
  3296. retrans = rp->retrans;
  3297. retry = rp->retry;
  3298. ndots = rp->ndots;
  3299. }
  3300. memset(rp, 0, sizeof(*rp));
  3301. if (!preinit) {
  3302. rp->options = RES_DEFAULT;
  3303. rp->retrans = RES_TIMEOUT;
  3304. rp->retry = RES_DFLRETRY;
  3305. rp->ndots = 1;
  3306. } else {
  3307. rp->options = options;
  3308. rp->retrans = retrans;
  3309. rp->retry = retry;
  3310. rp->ndots = ndots;
  3311. }
  3312. #ifdef __UCLIBC_HAS_COMPAT_RES_STATE__
  3313. /* Was: "rp->id = random();" but:
  3314. * - random() pulls in largish static buffers
  3315. * - isn't actually random unless, say, srandom(time(NULL)) was called
  3316. * - is not used by uclibc anyway :)
  3317. */
  3318. /* rp->id = 0; - memset did it */
  3319. #endif
  3320. #ifdef __UCLIBC_HAS_EXTRA_COMPAT_RES_STATE__
  3321. rp->_vcsock = -1;
  3322. #endif
  3323. n = __searchdomains;
  3324. if (n > ARRAY_SIZE(rp->dnsrch))
  3325. n = ARRAY_SIZE(rp->dnsrch);
  3326. for (i = 0; i < n; i++)
  3327. rp->dnsrch[i] = __searchdomain[i];
  3328. /* copy nameservers' addresses */
  3329. i = 0;
  3330. #ifdef __UCLIBC_HAS_IPV4__
  3331. n = 0;
  3332. while (n < ARRAY_SIZE(rp->nsaddr_list) && i < __nameservers) {
  3333. if (__nameserver[i].sa.sa_family == AF_INET) {
  3334. rp->nsaddr_list[n] = __nameserver[i].sa4; /* struct copy */
  3335. #ifdef __UCLIBC_HAS_IPV6__
  3336. if (m < ARRAY_SIZE(rp->_u._ext.nsaddrs)) {
  3337. rp->_u._ext.nsaddrs[m] = (void*) &rp->nsaddr_list[n];
  3338. m++;
  3339. }
  3340. #endif
  3341. n++;
  3342. }
  3343. #ifdef __UCLIBC_HAS_IPV6__
  3344. if (__nameserver[i].sa.sa_family == AF_INET6
  3345. && m < ARRAY_SIZE(rp->_u._ext.nsaddrs)
  3346. ) {
  3347. struct sockaddr_in6 *sa6 = malloc(sizeof(*sa6));
  3348. if (sa6) {
  3349. *sa6 = __nameserver[i].sa6; /* struct copy */
  3350. rp->_u._ext.nsaddrs[m] = sa6;
  3351. m++;
  3352. }
  3353. }
  3354. #endif
  3355. i++;
  3356. }
  3357. rp->nscount = n;
  3358. #ifdef __UCLIBC_HAS_IPV6__
  3359. rp->_u._ext.nscount = m;
  3360. #endif
  3361. #else /* IPv6 only */
  3362. while (m < ARRAY_SIZE(rp->_u._ext.nsaddrs) && i < __nameservers) {
  3363. struct sockaddr_in6 *sa6 = malloc(sizeof(*sa6));
  3364. if (sa6) {
  3365. *sa6 = __nameserver[i].sa6; /* struct copy */
  3366. rp->_u._ext.nsaddrs[m] = sa6;
  3367. m++;
  3368. }
  3369. i++;
  3370. }
  3371. rp->_u._ext.nscount = m;
  3372. #endif
  3373. rp->options |= RES_INIT;
  3374. return 0;
  3375. }
  3376. static unsigned int
  3377. res_randomid(void)
  3378. {
  3379. return 0xffff & getpid();
  3380. }
  3381. /* Our res_init never fails (always returns 0) */
  3382. int
  3383. res_init(void)
  3384. {
  3385. /*
  3386. * These three fields used to be statically initialized. This made
  3387. * it hard to use this code in a shared library. It is necessary,
  3388. * now that we're doing dynamic initialization here, that we preserve
  3389. * the old semantics: if an application modifies one of these three
  3390. * fields of _res before res_init() is called, res_init() will not
  3391. * alter them. Of course, if an application is setting them to
  3392. * _zero_ before calling res_init(), hoping to override what used
  3393. * to be the static default, we can't detect it and unexpected results
  3394. * will follow. Zero for any of these fields would make no sense,
  3395. * so one can safely assume that the applications were already getting
  3396. * unexpected results.
  3397. *
  3398. * _res.options is tricky since some apps were known to diddle the bits
  3399. * before res_init() was first called. We can't replicate that semantic
  3400. * with dynamic initialization (they may have turned bits off that are
  3401. * set in RES_DEFAULT). Our solution is to declare such applications
  3402. * "broken". They could fool us by setting RES_INIT but none do (yet).
  3403. */
  3404. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  3405. if (!_res.retrans)
  3406. _res.retrans = RES_TIMEOUT;
  3407. if (!_res.retry)
  3408. _res.retry = 4;
  3409. if (!(_res.options & RES_INIT))
  3410. _res.options = RES_DEFAULT;
  3411. /*
  3412. * This one used to initialize implicitly to zero, so unless the app
  3413. * has set it to something in particular, we can randomize it now.
  3414. */
  3415. if (!_res.id)
  3416. _res.id = res_randomid();
  3417. __res_sync = NULL;
  3418. __res_vinit(&_res, 1);
  3419. __res_sync = res_sync_func;
  3420. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  3421. return 0;
  3422. }
  3423. libc_hidden_def(res_init)
  3424. static void
  3425. __res_iclose(res_state statp)
  3426. {
  3427. struct __res_state * rp = statp;
  3428. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  3429. if (rp == NULL)
  3430. rp = __res_state();
  3431. __close_nameservers();
  3432. __res_sync = NULL;
  3433. #ifdef __UCLIBC_HAS_IPV6__
  3434. {
  3435. char *p1 = (char*) &(rp->nsaddr_list[0]);
  3436. unsigned int m = 0;
  3437. /* free nsaddrs[m] if they do not point to nsaddr_list[x] */
  3438. while (m < ARRAY_SIZE(rp->_u._ext.nsaddrs)) {
  3439. char *p2 = (char*)(rp->_u._ext.nsaddrs[m++]);
  3440. if (p2 < p1 || (p2 - p1) > (signed)sizeof(rp->nsaddr_list))
  3441. free(p2);
  3442. }
  3443. }
  3444. #endif
  3445. memset(rp, 0, sizeof(struct __res_state));
  3446. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  3447. }
  3448. /*
  3449. * This routine is for closing the socket if a virtual circuit is used and
  3450. * the program wants to close it. This provides support for endhostent()
  3451. * which expects to close the socket.
  3452. *
  3453. * This routine is not expected to be user visible.
  3454. */
  3455. void
  3456. res_nclose(res_state statp)
  3457. {
  3458. __res_iclose(statp);
  3459. }
  3460. #ifdef __UCLIBC_HAS_BSD_RES_CLOSE__
  3461. void res_close(void)
  3462. {
  3463. __res_iclose(NULL);
  3464. }
  3465. #endif
  3466. #ifdef __UCLIBC_HAS_BSD_B64_NTOP_B64_PTON__
  3467. #define Assert(Cond) if (!(Cond)) abort()
  3468. static const char Base64[] =
  3469. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  3470. static const char Pad64 = '=';
  3471. /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
  3472. The following encoding technique is taken from RFC 1521 by Borenstein
  3473. and Freed. It is reproduced here in a slightly edited form for
  3474. convenience.
  3475. A 65-character subset of US-ASCII is used, enabling 6 bits to be
  3476. represented per printable character. (The extra 65th character, "=",
  3477. is used to signify a special processing function.)
  3478. The encoding process represents 24-bit groups of input bits as output
  3479. strings of 4 encoded characters. Proceeding from left to right, a
  3480. 24-bit input group is formed by concatenating 3 8-bit input groups.
  3481. These 24 bits are then treated as 4 concatenated 6-bit groups, each
  3482. of which is translated into a single digit in the base64 alphabet.
  3483. Each 6-bit group is used as an index into an array of 64 printable
  3484. characters. The character referenced by the index is placed in the
  3485. output string.
  3486. Table 1: The Base64 Alphabet
  3487. Value Encoding Value Encoding Value Encoding Value Encoding
  3488. 0 A 17 R 34 i 51 z
  3489. 1 B 18 S 35 j 52 0
  3490. 2 C 19 T 36 k 53 1
  3491. 3 D 20 U 37 l 54 2
  3492. 4 E 21 V 38 m 55 3
  3493. 5 F 22 W 39 n 56 4
  3494. 6 G 23 X 40 o 57 5
  3495. 7 H 24 Y 41 p 58 6
  3496. 8 I 25 Z 42 q 59 7
  3497. 9 J 26 a 43 r 60 8
  3498. 10 K 27 b 44 s 61 9
  3499. 11 L 28 c 45 t 62 +
  3500. 12 M 29 d 46 u 63 /
  3501. 13 N 30 e 47 v
  3502. 14 O 31 f 48 w (pad) =
  3503. 15 P 32 g 49 x
  3504. 16 Q 33 h 50 y
  3505. Special processing is performed if fewer than 24 bits are available
  3506. at the end of the data being encoded. A full encoding quantum is
  3507. always completed at the end of a quantity. When fewer than 24 input
  3508. bits are available in an input group, zero bits are added (on the
  3509. right) to form an integral number of 6-bit groups. Padding at the
  3510. end of the data is performed using the '=' character.
  3511. Since all base64 input is an integral number of octets, only the
  3512. -------------------------------------------------
  3513. following cases can arise:
  3514. (1) the final quantum of encoding input is an integral
  3515. multiple of 24 bits; here, the final unit of encoded
  3516. output will be an integral multiple of 4 characters
  3517. with no "=" padding,
  3518. (2) the final quantum of encoding input is exactly 8 bits;
  3519. here, the final unit of encoded output will be two
  3520. characters followed by two "=" padding characters, or
  3521. (3) the final quantum of encoding input is exactly 16 bits;
  3522. here, the final unit of encoded output will be three
  3523. characters followed by one "=" padding character.
  3524. */
  3525. int
  3526. b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
  3527. size_t datalength = 0;
  3528. u_char input[3];
  3529. u_char output[4];
  3530. size_t i;
  3531. while (2 < srclength) {
  3532. input[0] = *src++;
  3533. input[1] = *src++;
  3534. input[2] = *src++;
  3535. srclength -= 3;
  3536. output[0] = input[0] >> 2;
  3537. output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
  3538. output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
  3539. output[3] = input[2] & 0x3f;
  3540. Assert(output[0] < 64);
  3541. Assert(output[1] < 64);
  3542. Assert(output[2] < 64);
  3543. Assert(output[3] < 64);
  3544. if (datalength + 4 > targsize)
  3545. return (-1);
  3546. target[datalength++] = Base64[output[0]];
  3547. target[datalength++] = Base64[output[1]];
  3548. target[datalength++] = Base64[output[2]];
  3549. target[datalength++] = Base64[output[3]];
  3550. }
  3551. /* Now we worry about padding. */
  3552. if (0 != srclength) {
  3553. /* Get what's left. */
  3554. input[0] = input[1] = input[2] = '\0';
  3555. for (i = 0; i < srclength; i++)
  3556. input[i] = *src++;
  3557. output[0] = input[0] >> 2;
  3558. output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
  3559. output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
  3560. Assert(output[0] < 64);
  3561. Assert(output[1] < 64);
  3562. Assert(output[2] < 64);
  3563. if (datalength + 4 > targsize)
  3564. return (-1);
  3565. target[datalength++] = Base64[output[0]];
  3566. target[datalength++] = Base64[output[1]];
  3567. if (srclength == 1)
  3568. target[datalength++] = Pad64;
  3569. else
  3570. target[datalength++] = Base64[output[2]];
  3571. target[datalength++] = Pad64;
  3572. }
  3573. if (datalength >= targsize)
  3574. return (-1);
  3575. target[datalength] = '\0'; /* Returned value doesn't count \0. */
  3576. return (datalength);
  3577. }
  3578. /* libc_hidden_def (b64_ntop) */
  3579. /* skips all whitespace anywhere.
  3580. converts characters, four at a time, starting at (or after)
  3581. src from base - 64 numbers into three 8 bit bytes in the target area.
  3582. it returns the number of data bytes stored at the target, or -1 on error.
  3583. */
  3584. int
  3585. b64_pton (char const *src, u_char *target, size_t targsize)
  3586. {
  3587. int tarindex, state, ch;
  3588. char *pos;
  3589. state = 0;
  3590. tarindex = 0;
  3591. while ((ch = *src++) != '\0') {
  3592. if (isspace(ch)) /* Skip whitespace anywhere. */
  3593. continue;
  3594. if (ch == Pad64)
  3595. break;
  3596. pos = strchr(Base64, ch);
  3597. if (pos == 0) /* A non-base64 character. */
  3598. return (-1);
  3599. switch (state) {
  3600. case 0:
  3601. if (target) {
  3602. if ((size_t)tarindex >= targsize)
  3603. return (-1);
  3604. target[tarindex] = (pos - Base64) << 2;
  3605. }
  3606. state = 1;
  3607. break;
  3608. case 1:
  3609. if (target) {
  3610. if ((size_t)tarindex + 1 >= targsize)
  3611. return (-1);
  3612. target[tarindex] |= (pos - Base64) >> 4;
  3613. target[tarindex+1] = ((pos - Base64) & 0x0f)
  3614. << 4 ;
  3615. }
  3616. tarindex++;
  3617. state = 2;
  3618. break;
  3619. case 2:
  3620. if (target) {
  3621. if ((size_t)tarindex + 1 >= targsize)
  3622. return (-1);
  3623. target[tarindex] |= (pos - Base64) >> 2;
  3624. target[tarindex+1] = ((pos - Base64) & 0x03)
  3625. << 6;
  3626. }
  3627. tarindex++;
  3628. state = 3;
  3629. break;
  3630. case 3:
  3631. if (target) {
  3632. if ((size_t)tarindex >= targsize)
  3633. return (-1);
  3634. target[tarindex] |= (pos - Base64);
  3635. }
  3636. tarindex++;
  3637. state = 0;
  3638. break;
  3639. default:
  3640. abort();
  3641. }
  3642. }
  3643. /*
  3644. * We are done decoding Base-64 chars. Let's see if we ended
  3645. * on a byte boundary, and/or with erroneous trailing characters.
  3646. */
  3647. if (ch == Pad64) { /* We got a pad char. */
  3648. ch = *src++; /* Skip it, get next. */
  3649. switch (state) {
  3650. case 0: /* Invalid = in first position */
  3651. case 1: /* Invalid = in second position */
  3652. return (-1);
  3653. case 2: /* Valid, means one byte of info */
  3654. /* Skip any number of spaces. */
  3655. for ((void)NULL; ch != '\0'; ch = *src++)
  3656. if (!isspace(ch))
  3657. break;
  3658. /* Make sure there is another trailing = sign. */
  3659. if (ch != Pad64)
  3660. return (-1);
  3661. ch = *src++; /* Skip the = */
  3662. /* Fall through to "single trailing =" case. */
  3663. /* FALLTHROUGH */
  3664. case 3: /* Valid, means two bytes of info */
  3665. /*
  3666. * We know this char is an =. Is there anything but
  3667. * whitespace after it?
  3668. */
  3669. for ((void)NULL; ch != '\0'; ch = *src++)
  3670. if (!isspace(ch))
  3671. return (-1);
  3672. /*
  3673. * Now make sure for cases 2 and 3 that the "extra"
  3674. * bits that slopped past the last full byte were
  3675. * zeros. If we don't check them, they become a
  3676. * subliminal channel.
  3677. */
  3678. if (target && target[tarindex] != 0)
  3679. return (-1);
  3680. }
  3681. } else {
  3682. /*
  3683. * We ended by seeing the end of the string. Make sure we
  3684. * have no partial bytes lying around.
  3685. */
  3686. if (state != 0)
  3687. return (-1);
  3688. }
  3689. return (tarindex);
  3690. }
  3691. #endif
  3692. /* This needs to be after the use of _res in res_init, above. */
  3693. #undef _res
  3694. #ifndef __UCLIBC_HAS_THREADS__
  3695. /* The resolver state for use by single-threaded programs.
  3696. This differs from plain `struct __res_state _res;' in that it doesn't
  3697. create a common definition, but a plain symbol that resides in .bss,
  3698. which can have an alias. */
  3699. struct __res_state _res __attribute__((section (".bss")));
  3700. struct __res_state *__resp = &_res;
  3701. #else /* __UCLIBC_HAS_THREADS__ */
  3702. struct __res_state _res __attribute__((section (".bss"))) attribute_hidden;
  3703. # if defined __UCLIBC_HAS_TLS__
  3704. # undef __resp
  3705. __thread struct __res_state *__resp = &_res;
  3706. extern __thread struct __res_state *__libc_resp
  3707. __attribute__ ((alias ("__resp"))) attribute_hidden attribute_tls_model_ie;
  3708. # else
  3709. # undef __resp
  3710. struct __res_state *__resp = &_res;
  3711. # endif
  3712. #endif /* !__UCLIBC_HAS_THREADS__ */
  3713. /*
  3714. * Set up default settings. If the configuration file exist, the values
  3715. * there will have precedence. Otherwise, the server address is set to
  3716. * INADDR_ANY and the default domain name comes from the gethostname().
  3717. *
  3718. * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
  3719. * rather than INADDR_ANY ("0.0.0.0") as the default name server address
  3720. * since it was noted that INADDR_ANY actually meant ``the first interface
  3721. * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
  3722. * it had to be "up" in order for you to reach your own name server. It
  3723. * was later decided that since the recommended practice is to always
  3724. * install local static routes through 127.0.0.1 for all your network
  3725. * interfaces, that we could solve this problem without a code change.
  3726. *
  3727. * The configuration file should always be used, since it is the only way
  3728. * to specify a default domain. If you are running a server on your local
  3729. * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
  3730. * in the configuration file.
  3731. *
  3732. * Return 0 if completes successfully, -1 on error
  3733. */
  3734. int
  3735. res_ninit(res_state statp)
  3736. {
  3737. int ret;
  3738. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  3739. ret = __res_vinit(statp, 0);
  3740. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  3741. return ret;
  3742. }
  3743. #endif /* L_res_init */
  3744. #ifdef L_res_state
  3745. # if !defined __UCLIBC_HAS_TLS__
  3746. extern struct __res_state *__resp;
  3747. struct __res_state *
  3748. __res_state (void)
  3749. {
  3750. return __resp;
  3751. }
  3752. # else
  3753. # undef _res
  3754. extern struct __res_state _res;
  3755. /* When threaded, _res may be a per-thread variable. */
  3756. struct __res_state *
  3757. weak_const_function
  3758. __res_state (void)
  3759. {
  3760. return &_res;
  3761. }
  3762. # endif
  3763. #endif /* L_res_state */
  3764. #ifdef L_res_query
  3765. int res_query(const char *dname, int class, int type,
  3766. unsigned char *answer, int anslen)
  3767. {
  3768. int i;
  3769. unsigned char *packet = NULL;
  3770. struct resolv_answer a;
  3771. if (!dname || class != 1 /* CLASS_IN */) {
  3772. h_errno = NO_RECOVERY;
  3773. return -1;
  3774. }
  3775. memset(&a, '\0', sizeof(a));
  3776. i = __dns_lookup(dname, type, &packet, &a);
  3777. if (i < 0) {
  3778. if (!h_errno) /* TODO: can this ever happen? */
  3779. h_errno = TRY_AGAIN;
  3780. return -1;
  3781. }
  3782. free(a.dotted);
  3783. if (i > anslen)
  3784. i = anslen;
  3785. memcpy(answer, packet, i);
  3786. free(packet);
  3787. return i;
  3788. }
  3789. libc_hidden_def(res_query)
  3790. /*
  3791. * Formulate a normal query, send, and retrieve answer in supplied buffer.
  3792. * Return the size of the response on success, -1 on error.
  3793. * If enabled, implement search rules until answer or unrecoverable failure
  3794. * is detected. Error code, if any, is left in h_errno.
  3795. */
  3796. #define __TRAILING_DOT (1<<0)
  3797. #define __GOT_NODATA (1<<1)
  3798. #define __GOT_SERVFAIL (1<<2)
  3799. #define __TRIED_AS_IS (1<<3)
  3800. int res_search(const char *name, int class, int type, u_char *answer,
  3801. int anslen)
  3802. {
  3803. const char *cp;
  3804. char **domain;
  3805. HEADER *hp = (HEADER *)(void *)answer;
  3806. unsigned dots;
  3807. unsigned state;
  3808. int ret, saved_herrno;
  3809. uint32_t _res_options;
  3810. unsigned _res_ndots;
  3811. char **_res_dnsrch;
  3812. if (!name || !answer) {
  3813. h_errno = NETDB_INTERNAL;
  3814. return -1;
  3815. }
  3816. again:
  3817. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  3818. _res_options = _res.options;
  3819. _res_ndots = _res.ndots;
  3820. _res_dnsrch = _res.dnsrch;
  3821. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  3822. if (!(_res_options & RES_INIT)) {
  3823. res_init(); /* our res_init never fails */
  3824. goto again;
  3825. }
  3826. state = 0;
  3827. errno = 0;
  3828. h_errno = HOST_NOT_FOUND; /* default, if we never query */
  3829. dots = 0;
  3830. for (cp = name; *cp; cp++)
  3831. dots += (*cp == '.');
  3832. if (cp > name && *--cp == '.')
  3833. state |= __TRAILING_DOT;
  3834. /*
  3835. * If there are dots in the name already, let's just give it a try
  3836. * 'as is'. The threshold can be set with the "ndots" option.
  3837. */
  3838. saved_herrno = -1;
  3839. if (dots >= _res_ndots) {
  3840. ret = res_querydomain(name, NULL, class, type, answer, anslen);
  3841. if (ret > 0)
  3842. return ret;
  3843. saved_herrno = h_errno;
  3844. state |= __TRIED_AS_IS;
  3845. }
  3846. /*
  3847. * We do at least one level of search if
  3848. * - there is no dot and RES_DEFNAME is set, or
  3849. * - there is at least one dot, there is no trailing dot,
  3850. * and RES_DNSRCH is set.
  3851. */
  3852. if ((!dots && (_res_options & RES_DEFNAMES))
  3853. || (dots && !(state & __TRAILING_DOT) && (_res_options & RES_DNSRCH))
  3854. ) {
  3855. bool done = 0;
  3856. for (domain = _res_dnsrch; *domain && !done; domain++) {
  3857. ret = res_querydomain(name, *domain, class, type,
  3858. answer, anslen);
  3859. if (ret > 0)
  3860. return ret;
  3861. /*
  3862. * If no server present, give up.
  3863. * If name isn't found in this domain,
  3864. * keep trying higher domains in the search list
  3865. * (if that's enabled).
  3866. * On a NO_DATA error, keep trying, otherwise
  3867. * a wildcard entry of another type could keep us
  3868. * from finding this entry higher in the domain.
  3869. * If we get some other error (negative answer or
  3870. * server failure), then stop searching up,
  3871. * but try the input name below in case it's
  3872. * fully-qualified.
  3873. */
  3874. if (errno == ECONNREFUSED) {
  3875. h_errno = TRY_AGAIN;
  3876. return -1;
  3877. }
  3878. switch (h_errno) {
  3879. case NO_DATA:
  3880. state |= __GOT_NODATA;
  3881. /* FALLTHROUGH */
  3882. case HOST_NOT_FOUND:
  3883. /* keep trying */
  3884. break;
  3885. case TRY_AGAIN:
  3886. if (hp->rcode == SERVFAIL) {
  3887. /* try next search element, if any */
  3888. state |= __GOT_SERVFAIL;
  3889. break;
  3890. }
  3891. /* FALLTHROUGH */
  3892. default:
  3893. /* anything else implies that we're done */
  3894. done = 1;
  3895. }
  3896. /*
  3897. * if we got here for some reason other than DNSRCH,
  3898. * we only wanted one iteration of the loop, so stop.
  3899. */
  3900. if (!(_res_options & RES_DNSRCH))
  3901. done = 1;
  3902. }
  3903. }
  3904. /*
  3905. * if we have not already tried the name "as is", do that now.
  3906. * note that we do this regardless of how many dots were in the
  3907. * name or whether it ends with a dot.
  3908. */
  3909. if (!(state & __TRIED_AS_IS)) {
  3910. ret = res_querydomain(name, NULL, class, type, answer, anslen);
  3911. if (ret > 0)
  3912. return ret;
  3913. }
  3914. /*
  3915. * if we got here, we didn't satisfy the search.
  3916. * if we did an initial full query, return that query's h_errno
  3917. * (note that we wouldn't be here if that query had succeeded).
  3918. * else if we ever got a nodata, send that back as the reason.
  3919. * else send back meaningless h_errno, that being the one from
  3920. * the last DNSRCH we did.
  3921. */
  3922. if (saved_herrno != -1)
  3923. h_errno = saved_herrno;
  3924. else if (state & __GOT_NODATA)
  3925. h_errno = NO_DATA;
  3926. else if (state & __GOT_SERVFAIL)
  3927. h_errno = TRY_AGAIN;
  3928. return -1;
  3929. }
  3930. #undef __TRAILING_DOT
  3931. #undef __GOT_NODATA
  3932. #undef __GOT_SERVFAIL
  3933. #undef __TRIED_AS_IS
  3934. /*
  3935. * Perform a call on res_query on the concatenation of name and domain,
  3936. * removing a trailing dot from name if domain is NULL.
  3937. */
  3938. int res_querydomain(const char *name, const char *domain, int class, int type,
  3939. u_char *answer, int anslen)
  3940. {
  3941. char nbuf[MAXDNAME];
  3942. const char *longname = nbuf;
  3943. size_t n, d;
  3944. #ifdef DEBUG
  3945. uint32_t _res_options;
  3946. #endif
  3947. if (!name || !answer) {
  3948. h_errno = NETDB_INTERNAL;
  3949. return -1;
  3950. }
  3951. #ifdef DEBUG
  3952. again:
  3953. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  3954. _res_options = _res.options;
  3955. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  3956. if (!(_res_options & RES_INIT)) {
  3957. res_init(); /* our res_init never fails */
  3958. goto again;
  3959. }
  3960. if (_res_options & RES_DEBUG)
  3961. printf(";; res_querydomain(%s, %s, %d, %d)\n",
  3962. name, (domain ? domain : "<Nil>"), class, type);
  3963. #endif
  3964. if (domain == NULL) {
  3965. /*
  3966. * Check for trailing '.';
  3967. * copy without '.' if present.
  3968. */
  3969. n = strlen(name);
  3970. if (n + 1 > sizeof(nbuf)) {
  3971. h_errno = NO_RECOVERY;
  3972. return -1;
  3973. }
  3974. if (n > 0 && name[--n] == '.') {
  3975. strncpy(nbuf, name, n);
  3976. nbuf[n] = '\0';
  3977. } else
  3978. longname = name;
  3979. } else {
  3980. n = strlen(name);
  3981. d = strlen(domain);
  3982. if (n + 1 + d + 1 > sizeof(nbuf)) {
  3983. h_errno = NO_RECOVERY;
  3984. return -1;
  3985. }
  3986. snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
  3987. }
  3988. return res_query(longname, class, type, answer, anslen);
  3989. }
  3990. libc_hidden_def(res_querydomain)
  3991. #endif /* L_res_query */
  3992. #ifdef L_ns_netint
  3993. unsigned int ns_get16(const unsigned char *src)
  3994. {
  3995. unsigned int dst;
  3996. NS_GET16(dst, src);
  3997. return dst;
  3998. }
  3999. unsigned long ns_get32(const unsigned char *src)
  4000. {
  4001. unsigned long dst;
  4002. NS_GET32(dst, src);
  4003. return dst;
  4004. }
  4005. void ns_put16(unsigned int src, unsigned char *dst)
  4006. {
  4007. NS_PUT16(src, dst);
  4008. }
  4009. void ns_put32(unsigned long src, unsigned char *dst)
  4010. {
  4011. NS_PUT32(src, dst);
  4012. }
  4013. #endif /* L_ns_netint */
  4014. #ifdef L_ns_parse
  4015. /* These need to be in the same order as the nres.h:ns_flag enum. */
  4016. struct _ns_flagdata { unsigned short mask, shift; };
  4017. static const struct _ns_flagdata _ns_flagdata[16] = {
  4018. { 0x8000, 15 }, /*%< qr. */
  4019. { 0x7800, 11 }, /*%< opcode. */
  4020. { 0x0400, 10 }, /*%< aa. */
  4021. { 0x0200, 9 }, /*%< tc. */
  4022. { 0x0100, 8 }, /*%< rd. */
  4023. { 0x0080, 7 }, /*%< ra. */
  4024. { 0x0040, 6 }, /*%< z. */
  4025. { 0x0020, 5 }, /*%< ad. */
  4026. { 0x0010, 4 }, /*%< cd. */
  4027. { 0x000f, 0 }, /*%< rcode. */
  4028. { 0x0000, 0 }, /*%< expansion (1/6). */
  4029. { 0x0000, 0 }, /*%< expansion (2/6). */
  4030. { 0x0000, 0 }, /*%< expansion (3/6). */
  4031. { 0x0000, 0 }, /*%< expansion (4/6). */
  4032. { 0x0000, 0 }, /*%< expansion (5/6). */
  4033. { 0x0000, 0 }, /*%< expansion (6/6). */
  4034. };
  4035. static void setsection(ns_msg *msg, ns_sect sect)
  4036. {
  4037. msg->_sect = sect;
  4038. if (sect == ns_s_max) {
  4039. msg->_rrnum = -1;
  4040. msg->_ptr = NULL;
  4041. } else {
  4042. msg->_rrnum = 0;
  4043. msg->_ptr = msg->_sections[(int)sect];
  4044. }
  4045. }
  4046. int ns_skiprr(const unsigned char *ptr,
  4047. const unsigned char *eom,
  4048. ns_sect section, int count)
  4049. {
  4050. const u_char *optr = ptr;
  4051. for (; count > 0; count--) {
  4052. int b, rdlength;
  4053. b = dn_skipname(ptr, eom);
  4054. if (b < 0) {
  4055. errno = EMSGSIZE;
  4056. return -1;
  4057. }
  4058. ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
  4059. if (section != ns_s_qd) {
  4060. if (ptr + NS_INT32SZ + NS_INT16SZ > eom) {
  4061. errno = EMSGSIZE;
  4062. return -1;
  4063. }
  4064. ptr += NS_INT32SZ/*TTL*/;
  4065. NS_GET16(rdlength, ptr);
  4066. ptr += rdlength/*RData*/;
  4067. }
  4068. }
  4069. if (ptr > eom) {
  4070. errno = EMSGSIZE;
  4071. return -1;
  4072. }
  4073. return ptr - optr;
  4074. }
  4075. libc_hidden_def(ns_skiprr)
  4076. int
  4077. ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle)
  4078. {
  4079. const u_char *eom = msg + msglen;
  4080. int i;
  4081. handle->_msg = msg;
  4082. handle->_eom = eom;
  4083. if (msg + NS_INT16SZ > eom) {
  4084. errno = EMSGSIZE;
  4085. return -1;
  4086. }
  4087. NS_GET16(handle->_id, msg);
  4088. if (msg + NS_INT16SZ > eom) {
  4089. errno = EMSGSIZE;
  4090. return -1;
  4091. }
  4092. NS_GET16(handle->_flags, msg);
  4093. for (i = 0; i < ns_s_max; i++) {
  4094. if (msg + NS_INT16SZ > eom) {
  4095. errno = EMSGSIZE;
  4096. return -1;
  4097. }
  4098. NS_GET16(handle->_counts[i], msg);
  4099. }
  4100. for (i = 0; i < ns_s_max; i++)
  4101. if (handle->_counts[i] == 0)
  4102. handle->_sections[i] = NULL;
  4103. else {
  4104. int b = ns_skiprr(msg, eom, (ns_sect)i,
  4105. handle->_counts[i]);
  4106. if (b < 0)
  4107. return -1;
  4108. handle->_sections[i] = msg;
  4109. msg += b;
  4110. }
  4111. if (msg != eom) {
  4112. errno = EMSGSIZE;
  4113. return -1;
  4114. }
  4115. setsection(handle, ns_s_max);
  4116. return 0;
  4117. }
  4118. int
  4119. ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
  4120. {
  4121. int b;
  4122. int tmp;
  4123. /* Make section right. */
  4124. tmp = section;
  4125. if (tmp < 0 || section >= ns_s_max) {
  4126. errno = ENODEV;
  4127. return -1;
  4128. }
  4129. if (section != handle->_sect)
  4130. setsection(handle, section);
  4131. /* Make rrnum right. */
  4132. if (rrnum == -1)
  4133. rrnum = handle->_rrnum;
  4134. if (rrnum < 0 || rrnum >= handle->_counts[(int)section]) {
  4135. errno = ENODEV;
  4136. return -1;
  4137. }
  4138. if (rrnum < handle->_rrnum)
  4139. setsection(handle, section);
  4140. if (rrnum > handle->_rrnum) {
  4141. b = ns_skiprr(handle->_ptr, handle->_eom, section,
  4142. rrnum - handle->_rrnum);
  4143. if (b < 0)
  4144. return -1;
  4145. handle->_ptr += b;
  4146. handle->_rrnum = rrnum;
  4147. }
  4148. /* Do the parse. */
  4149. b = dn_expand(handle->_msg, handle->_eom,
  4150. handle->_ptr, rr->name, NS_MAXDNAME);
  4151. if (b < 0)
  4152. return -1;
  4153. handle->_ptr += b;
  4154. if (handle->_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom) {
  4155. errno = EMSGSIZE;
  4156. return -1;
  4157. }
  4158. NS_GET16(rr->type, handle->_ptr);
  4159. NS_GET16(rr->rr_class, handle->_ptr);
  4160. if (section == ns_s_qd) {
  4161. rr->ttl = 0;
  4162. rr->rdlength = 0;
  4163. rr->rdata = NULL;
  4164. } else {
  4165. if (handle->_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom) {
  4166. errno = EMSGSIZE;
  4167. return -1;
  4168. }
  4169. NS_GET32(rr->ttl, handle->_ptr);
  4170. NS_GET16(rr->rdlength, handle->_ptr);
  4171. if (handle->_ptr + rr->rdlength > handle->_eom) {
  4172. errno = EMSGSIZE;
  4173. return -1;
  4174. }
  4175. rr->rdata = handle->_ptr;
  4176. handle->_ptr += rr->rdlength;
  4177. }
  4178. if (++handle->_rrnum > handle->_counts[(int)section])
  4179. setsection(handle, (ns_sect)((int)section + 1));
  4180. return 0;
  4181. }
  4182. int ns_msg_getflag(ns_msg handle, int flag)
  4183. {
  4184. return ((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift;
  4185. }
  4186. #endif /* L_ns_parse */
  4187. #ifdef L_res_data
  4188. int res_mkquery(int op, const char *dname, int class, int type,
  4189. const unsigned char *data, int datalen,
  4190. const unsigned char *newrr_in,
  4191. unsigned char *buf, int buflen)
  4192. {
  4193. HEADER *hp;
  4194. unsigned char *cp, *ep;
  4195. unsigned char *dnptrs[20], **dpp, **lastdnptr;
  4196. uint32_t _res_options;
  4197. int n;
  4198. if (!buf || buflen < HFIXEDSZ) {
  4199. h_errno = NETDB_INTERNAL;
  4200. return -1;
  4201. }
  4202. again:
  4203. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  4204. _res_options = _res.options;
  4205. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  4206. if (!(_res_options & RES_INIT)) {
  4207. res_init(); /* our res_init never fails */
  4208. goto again;
  4209. }
  4210. #ifdef DEBUG
  4211. if (_res_options & RES_DEBUG)
  4212. printf(";; res_mkquery(%d, %s, %d, %d)\n",
  4213. op, dname && *dname ? dname : "<null>", class, type);
  4214. #endif
  4215. memset(buf, 0, HFIXEDSZ);
  4216. hp = (HEADER *) buf;
  4217. hp->id = getpid() & 0xffff;
  4218. hp->opcode = op;
  4219. hp->rd = (_res_options & RES_RECURSE) != 0U;
  4220. hp->rcode = NOERROR;
  4221. cp = buf + HFIXEDSZ;
  4222. ep = buf + buflen;
  4223. dpp = dnptrs;
  4224. *dpp++ = buf;
  4225. *dpp++ = NULL;
  4226. lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
  4227. /*
  4228. * perform opcode specific processing
  4229. */
  4230. switch (op) {
  4231. case QUERY:
  4232. case NS_NOTIFY_OP:
  4233. if (ep - cp < QFIXEDSZ)
  4234. return -1;
  4235. n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs, lastdnptr);
  4236. if (n < 0)
  4237. return -1;
  4238. cp += n;
  4239. NS_PUT16(type, cp);
  4240. NS_PUT16(class, cp);
  4241. hp->qdcount = htons(1);
  4242. if (op == QUERY || data == NULL)
  4243. break;
  4244. /*
  4245. * Make an additional record for completion domain.
  4246. */
  4247. if ((ep - cp) < RRFIXEDSZ)
  4248. return -1;
  4249. n = dn_comp((const char *)data, cp, ep - cp - RRFIXEDSZ,
  4250. dnptrs, lastdnptr);
  4251. if (n < 0)
  4252. return -1;
  4253. cp += n;
  4254. NS_PUT16(T_NULL, cp);
  4255. NS_PUT16(class, cp);
  4256. NS_PUT32(0, cp);
  4257. NS_PUT16(0, cp);
  4258. hp->arcount = htons(1);
  4259. break;
  4260. case IQUERY:
  4261. /*
  4262. * Initialize answer section
  4263. */
  4264. if (ep - cp < 1 + RRFIXEDSZ + datalen)
  4265. return -1;
  4266. *cp++ = '\0'; /*%< no domain name */
  4267. NS_PUT16(type, cp);
  4268. NS_PUT16(class, cp);
  4269. NS_PUT32(0, cp);
  4270. NS_PUT16(datalen, cp);
  4271. if (datalen) {
  4272. memcpy(cp, data, (size_t)datalen);
  4273. cp += datalen;
  4274. }
  4275. hp->ancount = htons(1);
  4276. break;
  4277. default:
  4278. return -1;
  4279. }
  4280. return cp - buf;
  4281. }
  4282. #endif /* L_res_data */
  4283. /* Unimplemented: */
  4284. /* res_send */