resolv.c 84 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249
  1. /* vi: set sw=4 ts=4: */
  2. /* resolv.c: DNS Resolver
  3. *
  4. * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
  5. * The Silver Hammer Group, Ltd.
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Library General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2 of the License, or (at your option) any later version.
  11. */
  12. /*
  13. * Portions Copyright (c) 1985, 1993
  14. * The Regents of the University of California. All rights reserved.
  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. /*
  76. * 5-Oct-2000 W. Greathouse wgreathouse@smva.com
  77. * Fix memory leak and memory corruption.
  78. * -- Every name resolution resulted in
  79. * a new parse of resolv.conf and new
  80. * copy of nameservers allocated by
  81. * strdup.
  82. * -- Every name resolution resulted in
  83. * a new read of resolv.conf without
  84. * resetting index from prior read...
  85. * resulting in exceeding array bounds.
  86. *
  87. * Limit nameservers read from resolv.conf.
  88. * Add "search" domains from resolv.conf.
  89. * Some systems will return a security
  90. * signature along with query answer for
  91. * dynamic DNS entries -- skip/ignore this answer.
  92. * Include arpa/nameser.h for defines.
  93. * General cleanup.
  94. *
  95. * 20-Jun-2001 Michal Moskal <malekith@pld.org.pl>
  96. * partial IPv6 support (i.e. gethostbyname2() and resolve_address2()
  97. * functions added), IPv6 nameservers are also supported.
  98. *
  99. * 6-Oct-2001 Jari Korva <jari.korva@iki.fi>
  100. * more IPv6 support (IPv6 support for gethostbyaddr();
  101. * address family parameter and improved IPv6 support for get_hosts_byname
  102. * and read_etc_hosts; getnameinfo() port from glibc; defined
  103. * defined ip6addr_any and in6addr_loopback)
  104. *
  105. * 2-Feb-2002 Erik Andersen <andersen@codepoet.org>
  106. * Added gethostent(), sethostent(), and endhostent()
  107. *
  108. * 17-Aug-2002 Manuel Novoa III <mjn3@codepoet.org>
  109. * Fixed __read_etc_hosts_r to return alias list, and modified buffer
  110. * allocation accordingly. See MAX_ALIASES and ALIAS_DIM below.
  111. * This fixes the segfault in the Python 2.2.1 socket test.
  112. *
  113. * 04-Jan-2003 Jay Kulpinski <jskulpin@berkshire.rr.com>
  114. * Fixed __decode_dotted to count the terminating null character
  115. * in a host name.
  116. *
  117. * 02-Oct-2003 Tony J. White <tjw@tjw.org>
  118. * Lifted dn_expand() and dependent ns_name_uncompress(), ns_name_unpack(),
  119. * and ns_name_ntop() from glibc 2.3.2 for compatibility with ipsec-tools
  120. * and openldap.
  121. *
  122. * 7-Sep-2004 Erik Andersen <andersen@codepoet.org>
  123. * Added gethostent_r()
  124. *
  125. * 2008, 2009 Denys Vlasenko <vda.linux@googlemail.com>
  126. * Cleanups, fixes, readability, more cleanups and more fixes.
  127. */
  128. /* Nota bene:
  129. * The whole resolver code has several (severe) problems:
  130. * - it doesn't even build without IPv4, i.e. !UCLIBC_HAS_IPV4 but only IPv6
  131. * - it is way too big
  132. *
  133. * Both points above are considered bugs, patches/reimplementations welcome.
  134. */
  135. /* RFC 1035
  136. ...
  137. Whenever an octet represents a numeric quantity, the left most bit
  138. in the diagram is the high order or most significant bit.
  139. That is, the bit labeled 0 is the most significant bit.
  140. ...
  141. 4.1.1. Header section format
  142. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  143. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  144. | ID |
  145. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  146. |QR| OPCODE |AA|TC|RD|RA| 0 0 0| RCODE |
  147. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  148. | QDCOUNT |
  149. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  150. | ANCOUNT |
  151. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  152. | NSCOUNT |
  153. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  154. | ARCOUNT |
  155. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  156. ID 16 bit random identifier assigned by querying peer.
  157. Used to match query/response.
  158. QR message is a query (0), or a response (1).
  159. OPCODE 0 standard query (QUERY)
  160. 1 inverse query (IQUERY)
  161. 2 server status request (STATUS)
  162. AA Authoritative Answer - this bit is valid in responses.
  163. Responding name server is an authority for the domain name
  164. in question section. Answer section may have multiple owner names
  165. because of aliases. The AA bit corresponds to the name which matches
  166. the query name, or the first owner name in the answer section.
  167. TC TrunCation - this message was truncated.
  168. RD Recursion Desired - this bit may be set in a query and
  169. is copied into the response. If RD is set, it directs
  170. the name server to pursue the query recursively.
  171. Recursive query support is optional.
  172. RA Recursion Available - this be is set or cleared in a
  173. response, and denotes whether recursive query support is
  174. available in the name server.
  175. RCODE Response code.
  176. 0 No error condition
  177. 1 Format error
  178. 2 Server failure - server was unable to process the query
  179. due to a problem with the name server.
  180. 3 Name Error - meaningful only for responses from
  181. an authoritative name server. The referenced domain name
  182. does not exist.
  183. 4 Not Implemented.
  184. 5 Refused.
  185. QDCOUNT number of entries in the question section.
  186. ANCOUNT number of records in the answer section.
  187. NSCOUNT number of records in the authority records section.
  188. ARCOUNT number of records in the additional records section.
  189. 4.1.2. Question section format
  190. The section contains QDCOUNT (usually 1) entries, each of this format:
  191. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  192. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  193. / QNAME /
  194. / /
  195. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  196. | QTYPE |
  197. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  198. | QCLASS |
  199. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  200. QNAME a domain name represented as a sequence of labels, where
  201. each label consists of a length octet followed by that
  202. number of octets. The domain name terminates with the
  203. zero length octet for the null label of the root. Note
  204. that this field may be an odd number of octets; no
  205. padding is used.
  206. QTYPE a two octet type of the query.
  207. 1 a host address [REQ_A const]
  208. 2 an authoritative name server
  209. 3 a mail destination (Obsolete - use MX)
  210. 4 a mail forwarder (Obsolete - use MX)
  211. 5 the canonical name for an alias
  212. 6 marks the start of a zone of authority
  213. 7 a mailbox domain name (EXPERIMENTAL)
  214. 8 a mail group member (EXPERIMENTAL)
  215. 9 a mail rename domain name (EXPERIMENTAL)
  216. 10 a null RR (EXPERIMENTAL)
  217. 11 a well known service description
  218. 12 a domain name pointer [REQ_PTR const]
  219. 13 host information
  220. 14 mailbox or mail list information
  221. 15 mail exchange
  222. 16 text strings
  223. 0x1c IPv6?
  224. 252 a request for a transfer of an entire zone
  225. 253 a request for mailbox-related records (MB, MG or MR)
  226. 254 a request for mail agent RRs (Obsolete - see MX)
  227. 255 a request for all records
  228. QCLASS a two octet code that specifies the class of the query.
  229. 1 the Internet
  230. (others are historic only)
  231. 255 any class
  232. 4.1.3. Resource record format
  233. The answer, authority, and additional sections all share the same format:
  234. a variable number of resource records, where the number of records
  235. is specified in the corresponding count field in the header.
  236. Each resource record has this format:
  237. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  238. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  239. / /
  240. / NAME /
  241. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  242. | TYPE |
  243. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  244. | CLASS |
  245. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  246. | TTL |
  247. | |
  248. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  249. | RDLENGTH |
  250. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
  251. / RDATA /
  252. / /
  253. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  254. NAME a domain name to which this resource record pertains.
  255. TYPE two octets containing one of the RR type codes. This
  256. field specifies the meaning of the data in the RDATA field.
  257. CLASS two octets which specify the class of the data in the RDATA field.
  258. TTL a 32 bit unsigned integer that specifies the time interval
  259. (in seconds) that the record may be cached.
  260. RDLENGTH a 16 bit integer, length in octets of the RDATA field.
  261. RDATA a variable length string of octets that describes the resource.
  262. The format of this information varies according to the TYPE
  263. and CLASS of the resource record.
  264. If the TYPE is A and the CLASS is IN, it's a 4 octet IP address.
  265. 4.1.4. Message compression
  266. In order to reduce the size of messages, domain names can be compressed.
  267. An entire domain name or a list of labels at the end of a domain name
  268. is replaced with a pointer to a prior occurance of the same name.
  269. The pointer takes the form of a two octet sequence:
  270. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  271. | 1 1| OFFSET |
  272. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  273. The first two bits are ones. This allows a pointer to be distinguished
  274. from a label, since the label must begin with two zero bits because
  275. labels are restricted to 63 octets or less. The OFFSET field specifies
  276. an offset from the start of the message (i.e., the first octet
  277. of the ID field in the domain header).
  278. A zero offset specifies the first byte of the ID field, etc.
  279. Domain name in a message can be represented as either:
  280. - a sequence of labels ending in a zero octet
  281. - a pointer
  282. - a sequence of labels ending with a pointer
  283. */
  284. #define __FORCE_GLIBC
  285. #include <features.h>
  286. #include <string.h>
  287. #include <stdio.h>
  288. #include <signal.h>
  289. #include <errno.h>
  290. #include <sys/poll.h>
  291. #include <sys/socket.h>
  292. #include <sys/types.h>
  293. #include <sys/time.h>
  294. #include <netinet/in.h>
  295. #include <arpa/inet.h>
  296. #include <stdlib.h>
  297. #include <unistd.h>
  298. #include <resolv.h>
  299. #include <netdb.h>
  300. #include <ctype.h>
  301. #include <stdbool.h>
  302. #include <time.h>
  303. #include <arpa/nameser.h>
  304. #include <sys/utsname.h>
  305. #include <sys/un.h>
  306. #include <bits/uClibc_mutex.h>
  307. /* poll() is not supported in kernel <= 2.0, therefore if __NR_poll is
  308. * not available, we assume an old Linux kernel is in use and we will
  309. * use select() instead. */
  310. #include <sys/syscall.h>
  311. #ifndef __NR_poll
  312. # define USE_SELECT
  313. #endif
  314. #if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__
  315. #define IF_HAS_BOTH(...) __VA_ARGS__
  316. #else
  317. #define IF_HAS_BOTH(...)
  318. #endif
  319. #define MAX_RECURSE 5
  320. #define MAX_ALIASES 5
  321. /* 1:ip + 1:full + MAX_ALIASES:aliases + 1:NULL */
  322. #define ALIAS_DIM (2 + MAX_ALIASES + 1)
  323. #undef DEBUG
  324. /* #define DEBUG */
  325. #ifdef DEBUG
  326. #define DPRINTF(X,args...) fprintf(stderr, X, ##args)
  327. #else
  328. #define DPRINTF(X,args...)
  329. #endif
  330. #undef ARRAY_SIZE
  331. #define ARRAY_SIZE(v) (sizeof(v) / sizeof((v)[0]))
  332. /* Make sure the incoming char * buffer is aligned enough to handle our random
  333. * structures. This define is the same as we use for malloc alignment (which
  334. * has same requirements). The offset is the number of bytes we need to adjust
  335. * in order to attain desired alignment.
  336. */
  337. #define ALIGN_ATTR __alignof__(double __attribute_aligned__ (sizeof(size_t)))
  338. #define ALIGN_BUFFER_OFFSET(buf) ((ALIGN_ATTR - ((size_t)buf % ALIGN_ATTR)) % ALIGN_ATTR)
  339. /* Structs */
  340. struct resolv_header {
  341. int id;
  342. int qr, opcode, aa, tc, rd, ra, rcode;
  343. int qdcount;
  344. int ancount;
  345. int nscount;
  346. int arcount;
  347. };
  348. struct resolv_question {
  349. char *dotted;
  350. int qtype;
  351. int qclass;
  352. };
  353. struct resolv_answer {
  354. char *dotted;
  355. int atype;
  356. int aclass;
  357. int ttl;
  358. int rdlength;
  359. const unsigned char *rdata;
  360. int rdoffset;
  361. char* buf;
  362. size_t buflen;
  363. size_t add_count;
  364. };
  365. enum etc_hosts_action {
  366. GET_HOSTS_BYNAME = 0,
  367. GETHOSTENT,
  368. GET_HOSTS_BYADDR,
  369. };
  370. typedef union sockaddr46_t {
  371. struct sockaddr sa;
  372. #ifdef __UCLIBC_HAS_IPV4__
  373. struct sockaddr_in sa4;
  374. #endif
  375. #ifdef __UCLIBC_HAS_IPV6__
  376. struct sockaddr_in6 sa6;
  377. #endif
  378. } sockaddr46_t;
  379. __UCLIBC_MUTEX_EXTERN(__resolv_lock);
  380. /* Protected by __resolv_lock */
  381. extern void (*__res_sync)(void) attribute_hidden;
  382. /*extern uint32_t __resolv_opts attribute_hidden; */
  383. extern unsigned __nameservers attribute_hidden;
  384. extern unsigned __searchdomains attribute_hidden;
  385. extern sockaddr46_t *__nameserver attribute_hidden;
  386. extern char **__searchdomain attribute_hidden;
  387. #ifdef __UCLIBC_HAS_IPV4__
  388. extern const struct sockaddr_in __local_nameserver attribute_hidden;
  389. #else
  390. extern const struct sockaddr_in6 __local_nameserver attribute_hidden;
  391. #endif
  392. /* Arbitrary */
  393. #define MAXLEN_searchdomain 128
  394. /* function prototypes */
  395. extern int __get_hosts_byname_r(const char *name,
  396. int type,
  397. struct hostent *result_buf,
  398. char *buf,
  399. size_t buflen,
  400. struct hostent **result,
  401. int *h_errnop) attribute_hidden;
  402. extern int __get_hosts_byaddr_r(const char *addr,
  403. int len,
  404. int type,
  405. struct hostent *result_buf,
  406. char *buf,
  407. size_t buflen,
  408. struct hostent **result,
  409. int *h_errnop) attribute_hidden;
  410. extern FILE *__open_etc_hosts(void) attribute_hidden;
  411. extern int __read_etc_hosts_r(FILE *fp,
  412. const char *name,
  413. int type,
  414. enum etc_hosts_action action,
  415. struct hostent *result_buf,
  416. char *buf,
  417. size_t buflen,
  418. struct hostent **result,
  419. int *h_errnop) attribute_hidden;
  420. extern int __dns_lookup(const char *name,
  421. int type,
  422. unsigned char **outpacket,
  423. struct resolv_answer *a) attribute_hidden;
  424. extern int __encode_dotted(const char *dotted,
  425. unsigned char *dest,
  426. int maxlen) attribute_hidden;
  427. extern int __decode_dotted(const unsigned char *packet,
  428. int offset,
  429. int packet_len,
  430. char *dest,
  431. int dest_len) attribute_hidden;
  432. extern int __encode_header(struct resolv_header *h,
  433. unsigned char *dest,
  434. int maxlen) attribute_hidden;
  435. extern void __decode_header(unsigned char *data,
  436. struct resolv_header *h) attribute_hidden;
  437. extern int __encode_question(const struct resolv_question *q,
  438. unsigned char *dest,
  439. int maxlen) attribute_hidden;
  440. extern int __encode_answer(struct resolv_answer *a,
  441. unsigned char *dest,
  442. int maxlen) attribute_hidden;
  443. extern void __open_nameservers(void) attribute_hidden;
  444. extern void __close_nameservers(void) attribute_hidden;
  445. /*
  446. * Theory of operation.
  447. *
  448. * gethostbyname, getaddrinfo and friends end up here, and they sometimes
  449. * need to talk to DNS servers. In order to do this, we need to read /etc/resolv.conf
  450. * and determine servers' addresses and the like. resolv.conf format:
  451. *
  452. * nameserver <IP[v6]>
  453. * Address of DNS server. Cumulative.
  454. * If not specified, assumed to be on localhost.
  455. * search <domain1>[ <domain2>]...
  456. * Append these domains to unqualified names.
  457. * See ndots:n option.
  458. * $LOCALDOMAIN (space-separated list) overrides this.
  459. * domain <domain>
  460. * Effectively same as "search" with one domain.
  461. * If no "domain" line is present, the domain is determined
  462. * from the local host name returned by gethostname();
  463. * the domain part is taken to be everything after the first dot.
  464. * If there are no dots, there will be no "domain".
  465. * The domain and search keywords are mutually exclusive.
  466. * If more than one instance of these keywords is present,
  467. * the last instance wins.
  468. * sortlist 130.155.160.0[/255.255.240.0] 130.155.0.0
  469. * Allows addresses returned by gethostbyname to be sorted.
  470. * Not supported.
  471. * options option[ option]...
  472. * (so far we support none)
  473. * $RES_OPTIONS (space-separated list) is to be added to "options"
  474. * debug sets RES_DEBUG in _res.options
  475. * ndots:n how many dots there should be so that name will be tried
  476. * first as an absolute name before any search list elements
  477. * are appended to it. Default 1
  478. * timeout:n how long to wait for response. Default 5
  479. * (sun seems to have retrans:n synonym)
  480. * attempts:n number of rounds to do before giving up and returning
  481. * an error. Default 2
  482. * (sun seems to have retry:n synonym)
  483. * rotate sets RES_ROTATE in _res.options, round robin
  484. * selection of nameservers. Otherwise try
  485. * the first listed server first every time
  486. * no-check-names
  487. * sets RES_NOCHECKNAME in _res.options, which disables
  488. * checking of incoming host names for invalid characters
  489. * such as underscore (_), non-ASCII, or control characters
  490. * inet6 sets RES_USE_INET6 in _res.options. Try a AAAA query
  491. * before an A query inside the gethostbyname(), and map
  492. * IPv4 responses in IPv6 "tunnelled form" if no AAAA records
  493. * are found but an A record set exists
  494. * no_tld_query (FreeBSDism?)
  495. * do not attempt to resolve names without dots
  496. *
  497. * We will read and analyze /etc/resolv.conf as needed before
  498. * we do a DNS request. This happens in __dns_lookup.
  499. * (TODO: also re-parse it after a timeout, to catch updates).
  500. *
  501. * BSD has res_init routine which is used to initialize resolver state
  502. * which is held in global structure _res.
  503. * Generally, programs call res_init, then fiddle with _res.XXX
  504. * (_res.options and _res.nscount, _res.nsaddr_list[N]
  505. * are popular targets of fiddling) and expect subsequent calls
  506. * to gethostbyname, getaddrinfo, etc to use modified information.
  507. *
  508. * However, historical _res structure is quite awkward.
  509. * Using it for storing /etc/resolv.conf info is not desirable,
  510. * and __dns_lookup does not use it.
  511. *
  512. * We would like to avoid using it unless absolutely necessary.
  513. * If user doesn't use res_init, we should arrange it so that
  514. * _res structure doesn't even *get linked in* into user's application
  515. * (imagine static uclibc build here).
  516. *
  517. * The solution is a __res_sync function pointer, which is normally NULL.
  518. * But if res_init is called, it gets set and any subsequent gethostbyname
  519. * et al "syncronizes" our internal structures with potentially
  520. * modified _res.XXX stuff by calling __res_sync.
  521. * The trick here is that if res_init is not used and not linked in,
  522. * gethostbyname itself won't reference _res and _res won't be linked in
  523. * either. Other possible methods like
  524. * if (__res_sync_just_an_int_flag)
  525. * __sync_me_with_res()
  526. * would pull in __sync_me_with_res, which pulls in _res. Bad.
  527. */
  528. #ifdef L_encodeh
  529. int attribute_hidden __encode_header(struct resolv_header *h, unsigned char *dest, int maxlen)
  530. {
  531. if (maxlen < HFIXEDSZ)
  532. return -1;
  533. dest[0] = (h->id & 0xff00) >> 8;
  534. dest[1] = (h->id & 0x00ff) >> 0;
  535. dest[2] = (h->qr ? 0x80 : 0) |
  536. ((h->opcode & 0x0f) << 3) |
  537. (h->aa ? 0x04 : 0) |
  538. (h->tc ? 0x02 : 0) |
  539. (h->rd ? 0x01 : 0);
  540. dest[3] = (h->ra ? 0x80 : 0) | (h->rcode & 0x0f);
  541. dest[4] = (h->qdcount & 0xff00) >> 8;
  542. dest[5] = (h->qdcount & 0x00ff) >> 0;
  543. dest[6] = (h->ancount & 0xff00) >> 8;
  544. dest[7] = (h->ancount & 0x00ff) >> 0;
  545. dest[8] = (h->nscount & 0xff00) >> 8;
  546. dest[9] = (h->nscount & 0x00ff) >> 0;
  547. dest[10] = (h->arcount & 0xff00) >> 8;
  548. dest[11] = (h->arcount & 0x00ff) >> 0;
  549. return HFIXEDSZ;
  550. }
  551. #endif
  552. #ifdef L_decodeh
  553. void attribute_hidden __decode_header(unsigned char *data,
  554. struct resolv_header *h)
  555. {
  556. h->id = (data[0] << 8) | data[1];
  557. h->qr = (data[2] & 0x80) ? 1 : 0;
  558. h->opcode = (data[2] >> 3) & 0x0f;
  559. h->aa = (data[2] & 0x04) ? 1 : 0;
  560. h->tc = (data[2] & 0x02) ? 1 : 0;
  561. h->rd = (data[2] & 0x01) ? 1 : 0;
  562. h->ra = (data[3] & 0x80) ? 1 : 0;
  563. h->rcode = data[3] & 0x0f;
  564. h->qdcount = (data[4] << 8) | data[5];
  565. h->ancount = (data[6] << 8) | data[7];
  566. h->nscount = (data[8] << 8) | data[9];
  567. h->arcount = (data[10] << 8) | data[11];
  568. }
  569. #endif
  570. #ifdef L_encoded
  571. /* Encode a dotted string into nameserver transport-level encoding.
  572. This routine is fairly dumb, and doesn't attempt to compress
  573. the data */
  574. int attribute_hidden __encode_dotted(const char *dotted, unsigned char *dest, int maxlen)
  575. {
  576. unsigned used = 0;
  577. while (dotted && *dotted) {
  578. char *c = strchr(dotted, '.');
  579. int l = c ? c - dotted : strlen(dotted);
  580. /* two consecutive dots are not valid */
  581. if (l == 0)
  582. return -1;
  583. if (l >= (maxlen - used - 1))
  584. return -1;
  585. dest[used++] = l;
  586. memcpy(dest + used, dotted, l);
  587. used += l;
  588. if (!c)
  589. break;
  590. dotted = c + 1;
  591. }
  592. if (maxlen < 1)
  593. return -1;
  594. dest[used++] = 0;
  595. return used;
  596. }
  597. #endif
  598. #ifdef L_decoded
  599. /* Decode a dotted string from nameserver transport-level encoding.
  600. This routine understands compressed data. */
  601. int attribute_hidden __decode_dotted(const unsigned char *packet,
  602. int offset,
  603. int packet_len,
  604. char *dest,
  605. int dest_len)
  606. {
  607. unsigned b;
  608. bool measure = 1;
  609. unsigned total = 0;
  610. unsigned used = 0;
  611. if (!packet)
  612. return -1;
  613. while (1) {
  614. if (offset >= packet_len)
  615. return -1;
  616. b = packet[offset++];
  617. if (b == 0)
  618. break;
  619. if (measure)
  620. total++;
  621. if ((b & 0xc0) == 0xc0) {
  622. if (offset >= packet_len)
  623. return -1;
  624. if (measure)
  625. total++;
  626. /* compressed item, redirect */
  627. offset = ((b & 0x3f) << 8) | packet[offset];
  628. measure = 0;
  629. continue;
  630. }
  631. if (used + b + 1 >= dest_len)
  632. return -1;
  633. if (offset + b + 1 >= packet_len)
  634. return -1;
  635. memcpy(dest + used, packet + offset, b);
  636. offset += b;
  637. used += b;
  638. if (measure)
  639. total += b;
  640. if (packet[offset] != 0)
  641. dest[used++] = '.';
  642. else
  643. dest[used++] = '\0';
  644. }
  645. /* The null byte must be counted too */
  646. if (measure)
  647. total++;
  648. DPRINTF("Total decode len = %d\n", total);
  649. return total;
  650. }
  651. #endif
  652. #ifdef L_encodeq
  653. int attribute_hidden __encode_question(const struct resolv_question *q,
  654. unsigned char *dest,
  655. int maxlen)
  656. {
  657. int i;
  658. i = __encode_dotted(q->dotted, dest, maxlen);
  659. if (i < 0)
  660. return i;
  661. dest += i;
  662. maxlen -= i;
  663. if (maxlen < 4)
  664. return -1;
  665. dest[0] = (q->qtype & 0xff00) >> 8;
  666. dest[1] = (q->qtype & 0x00ff) >> 0;
  667. dest[2] = (q->qclass & 0xff00) >> 8;
  668. dest[3] = (q->qclass & 0x00ff) >> 0;
  669. return i + 4;
  670. }
  671. #endif
  672. #ifdef L_encodea
  673. int attribute_hidden __encode_answer(struct resolv_answer *a, unsigned char *dest, int maxlen)
  674. {
  675. int i;
  676. i = __encode_dotted(a->dotted, dest, maxlen);
  677. if (i < 0)
  678. return i;
  679. dest += i;
  680. maxlen -= i;
  681. if (maxlen < (RRFIXEDSZ + a->rdlength))
  682. return -1;
  683. *dest++ = (a->atype & 0xff00) >> 8;
  684. *dest++ = (a->atype & 0x00ff) >> 0;
  685. *dest++ = (a->aclass & 0xff00) >> 8;
  686. *dest++ = (a->aclass & 0x00ff) >> 0;
  687. *dest++ = (a->ttl & 0xff000000) >> 24;
  688. *dest++ = (a->ttl & 0x00ff0000) >> 16;
  689. *dest++ = (a->ttl & 0x0000ff00) >> 8;
  690. *dest++ = (a->ttl & 0x000000ff) >> 0;
  691. *dest++ = (a->rdlength & 0xff00) >> 8;
  692. *dest++ = (a->rdlength & 0x00ff) >> 0;
  693. memcpy(dest, a->rdata, a->rdlength);
  694. return i + RRFIXEDSZ + a->rdlength;
  695. }
  696. #endif
  697. #ifdef CURRENTLY_UNUSED
  698. #ifdef L_encodep
  699. int __encode_packet(struct resolv_header *h,
  700. struct resolv_question **q,
  701. struct resolv_answer **an,
  702. struct resolv_answer **ns,
  703. struct resolv_answer **ar,
  704. unsigned char *dest, int maxlen) attribute_hidden;
  705. int __encode_packet(struct resolv_header *h,
  706. struct resolv_question **q,
  707. struct resolv_answer **an,
  708. struct resolv_answer **ns,
  709. struct resolv_answer **ar,
  710. unsigned char *dest, int maxlen)
  711. {
  712. int i, total = 0;
  713. unsigned j;
  714. i = __encode_header(h, dest, maxlen);
  715. if (i < 0)
  716. return i;
  717. dest += i;
  718. maxlen -= i;
  719. total += i;
  720. for (j = 0; j < h->qdcount; j++) {
  721. i = __encode_question(q[j], dest, maxlen);
  722. if (i < 0)
  723. return i;
  724. dest += i;
  725. maxlen -= i;
  726. total += i;
  727. }
  728. for (j = 0; j < h->ancount; j++) {
  729. i = __encode_answer(an[j], dest, maxlen);
  730. if (i < 0)
  731. return i;
  732. dest += i;
  733. maxlen -= i;
  734. total += i;
  735. }
  736. for (j = 0; j < h->nscount; j++) {
  737. i = __encode_answer(ns[j], dest, maxlen);
  738. if (i < 0)
  739. return i;
  740. dest += i;
  741. maxlen -= i;
  742. total += i;
  743. }
  744. for (j = 0; j < h->arcount; j++) {
  745. i = __encode_answer(ar[j], dest, maxlen);
  746. if (i < 0)
  747. return i;
  748. dest += i;
  749. maxlen -= i;
  750. total += i;
  751. }
  752. return total;
  753. }
  754. #endif
  755. #ifdef L_decodep
  756. int __decode_packet(unsigned char *data, struct resolv_header *h) attribute_hidden;
  757. int __decode_packet(unsigned char *data, struct resolv_header *h)
  758. {
  759. __decode_header(data, h);
  760. return HFIXEDSZ;
  761. }
  762. #endif
  763. #ifdef L_formquery
  764. int __form_query(int id,
  765. const char *name,
  766. int type,
  767. unsigned char *packet,
  768. int maxlen);
  769. int __form_query(int id,
  770. const char *name,
  771. int type,
  772. unsigned char *packet,
  773. int maxlen)
  774. {
  775. struct resolv_header h;
  776. struct resolv_question q;
  777. int i, j;
  778. memset(&h, 0, sizeof(h));
  779. h.id = id;
  780. h.qdcount = 1;
  781. q.dotted = (char *) name;
  782. q.qtype = type;
  783. q.qclass = C_IN; /* CLASS_IN */
  784. i = __encode_header(&h, packet, maxlen);
  785. if (i < 0)
  786. return i;
  787. j = __encode_question(&q, packet + i, maxlen - i);
  788. if (j < 0)
  789. return j;
  790. return i + j;
  791. }
  792. #endif
  793. #endif /* CURRENTLY_UNUSED */
  794. #ifdef L_opennameservers
  795. # if __BYTE_ORDER == __LITTLE_ENDIAN
  796. #define NAMESERVER_PORT_N (__bswap_constant_16(NAMESERVER_PORT))
  797. #else
  798. #define NAMESERVER_PORT_N NAMESERVER_PORT
  799. #endif
  800. __UCLIBC_MUTEX_INIT(__resolv_lock, PTHREAD_MUTEX_INITIALIZER);
  801. /* Protected by __resolv_lock */
  802. void (*__res_sync)(void);
  803. /*uint32_t __resolv_opts; */
  804. unsigned __nameservers;
  805. unsigned __searchdomains;
  806. sockaddr46_t *__nameserver;
  807. char **__searchdomain;
  808. #ifdef __UCLIBC_HAS_IPV4__
  809. const struct sockaddr_in __local_nameserver = {
  810. .sin_family = AF_INET,
  811. .sin_port = NAMESERVER_PORT_N,
  812. };
  813. #else
  814. const struct sockaddr_in6 __local_nameserver = {
  815. .sin6_family = AF_INET6,
  816. .sin6_port = NAMESERVER_PORT_N,
  817. };
  818. #endif
  819. /* Helpers. Both stop on EOL, if it's '\n', it is converted to NUL first */
  820. static char *skip_nospace(char *p)
  821. {
  822. while (*p != '\0' && !isspace(*p)) {
  823. if (*p == '\n') {
  824. *p = '\0';
  825. break;
  826. }
  827. p++;
  828. }
  829. return p;
  830. }
  831. static char *skip_and_NUL_space(char *p)
  832. {
  833. /* NB: '\n' is not isspace! */
  834. while (1) {
  835. char c = *p;
  836. if (c == '\0' || !isspace(c))
  837. break;
  838. *p = '\0';
  839. if (c == '\n' || c == '#')
  840. break;
  841. p++;
  842. }
  843. return p;
  844. }
  845. /* Must be called under __resolv_lock. */
  846. void attribute_hidden __open_nameservers(void)
  847. {
  848. static uint8_t last_time;
  849. char szBuffer[MAXLEN_searchdomain];
  850. FILE *fp;
  851. int i;
  852. sockaddr46_t sa;
  853. if (!__res_sync) {
  854. /* Provide for periodic reread of /etc/resolv.conf */
  855. /* cur_time "ticks" every 256 seconds */
  856. uint8_t cur_time = ((unsigned)time(NULL)) >> 8;
  857. if (last_time != cur_time) {
  858. last_time = cur_time;
  859. __close_nameservers(); /* force config reread */
  860. }
  861. }
  862. if (__nameservers)
  863. goto sync;
  864. fp = fopen("/etc/resolv.conf", "r");
  865. if (!fp) {
  866. /* If we do not have a pre-populated /etc/resolv.conf then
  867. try to use the one from /etc/config which exists on numerous
  868. systems ranging from some uClinux to IRIX installations and
  869. may be the only /etc dir that was mounted rw. */
  870. fp = fopen("/etc/config/resolv.conf", "r");
  871. }
  872. if (fp) {
  873. while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
  874. void *ptr;
  875. char *keyword, *p;
  876. keyword = p = skip_and_NUL_space(szBuffer);
  877. /* skip keyword */
  878. p = skip_nospace(p);
  879. /* find next word */
  880. p = skip_and_NUL_space(p);
  881. if (strcmp(keyword, "nameserver") == 0) {
  882. /* terminate IP addr */
  883. *skip_nospace(p) = '\0';
  884. memset(&sa, 0, sizeof(sa));
  885. if (0) /* nothing */;
  886. #ifdef __UCLIBC_HAS_IPV6__
  887. else if (inet_pton(AF_INET6, p, &sa.sa6.sin6_addr) > 0) {
  888. sa.sa6.sin6_family = AF_INET6;
  889. sa.sa6.sin6_port = htons(NAMESERVER_PORT);
  890. }
  891. #endif
  892. #ifdef __UCLIBC_HAS_IPV4__
  893. else if (inet_pton(AF_INET, p, &sa.sa4.sin_addr) > 0) {
  894. sa.sa4.sin_family = AF_INET;
  895. sa.sa4.sin_port = htons(NAMESERVER_PORT);
  896. }
  897. #endif
  898. else
  899. continue; /* garbage on this line */
  900. ptr = realloc(__nameserver, (__nameservers + 1) * sizeof(__nameserver[0]));
  901. if (!ptr)
  902. continue;
  903. __nameserver = ptr;
  904. __nameserver[__nameservers++] = sa; /* struct copy */
  905. continue;
  906. }
  907. if (strcmp(keyword, "domain") == 0 || strcmp(keyword, "search") == 0) {
  908. char *p1;
  909. /* free old domains ("last 'domain' or 'search' wins" rule) */
  910. while (__searchdomains)
  911. free(__searchdomain[--__searchdomains]);
  912. /*free(__searchdomain);*/
  913. /*__searchdomain = NULL; - not necessary */
  914. next_word:
  915. /* terminate current word */
  916. p1 = skip_nospace(p);
  917. /* find next word (maybe) */
  918. p1 = skip_and_NUL_space(p1);
  919. /* add it */
  920. ptr = realloc(__searchdomain, (__searchdomains + 1) * sizeof(__searchdomain[0]));
  921. if (!ptr)
  922. continue;
  923. __searchdomain = ptr;
  924. /* NB: strlen(p) <= MAXLEN_searchdomain) because szBuffer[] is smaller */
  925. ptr = strdup(p);
  926. if (!ptr)
  927. continue;
  928. DPRINTF("adding search %s\n", (char*)ptr);
  929. __searchdomain[__searchdomains++] = (char*)ptr;
  930. p = p1;
  931. if (*p)
  932. goto next_word;
  933. continue;
  934. }
  935. /* if (strcmp(keyword, "sortlist") == 0)... */
  936. /* if (strcmp(keyword, "options") == 0)... */
  937. }
  938. fclose(fp);
  939. }
  940. if (__nameservers == 0) {
  941. /* Have to handle malloc failure! What a mess...
  942. * And it's not only here, we need to be careful
  943. * to never write into __nameserver[0] if it points
  944. * to constant __local_nameserver, or free it. */
  945. __nameserver = malloc(sizeof(__nameserver[0]));
  946. if (__nameserver)
  947. memcpy(__nameserver, &__local_nameserver, sizeof(__local_nameserver));
  948. else
  949. __nameserver = (void*) &__local_nameserver;
  950. __nameservers++;
  951. }
  952. if (__searchdomains == 0) {
  953. char buf[256];
  954. char *p;
  955. i = gethostname(buf, sizeof(buf) - 1);
  956. buf[sizeof(buf) - 1] = '\0';
  957. if (i == 0 && (p = strchr(buf, '.')) != NULL && p[1]) {
  958. p = strdup(p + 1);
  959. if (!p)
  960. goto err;
  961. __searchdomain = malloc(sizeof(__searchdomain[0]));
  962. if (!__searchdomain) {
  963. free(p);
  964. goto err;
  965. }
  966. __searchdomain[0] = p;
  967. __searchdomains++;
  968. err: ;
  969. }
  970. }
  971. DPRINTF("nameservers = %d\n", __nameservers);
  972. sync:
  973. if (__res_sync)
  974. __res_sync();
  975. }
  976. #endif
  977. #ifdef L_closenameservers
  978. /* Must be called under __resolv_lock. */
  979. void attribute_hidden __close_nameservers(void)
  980. {
  981. if (__nameserver != (void*) &__local_nameserver)
  982. free(__nameserver);
  983. __nameserver = NULL;
  984. __nameservers = 0;
  985. while (__searchdomains)
  986. free(__searchdomain[--__searchdomains]);
  987. free(__searchdomain);
  988. __searchdomain = NULL;
  989. /*__searchdomains = 0; - already is */
  990. }
  991. #endif
  992. #ifdef L_dnslookup
  993. /* Helpers */
  994. static int __length_question(const unsigned char *data, int maxlen)
  995. {
  996. const unsigned char *start;
  997. unsigned b;
  998. if (!data)
  999. return -1;
  1000. start = data;
  1001. while (1) {
  1002. if (maxlen <= 0)
  1003. return -1;
  1004. b = *data++;
  1005. if (b == 0)
  1006. break;
  1007. if ((b & 0xc0) == 0xc0) {
  1008. /* It's a "compressed" name. */
  1009. data++; /* skip lsb of redirected offset */
  1010. maxlen -= 2;
  1011. break;
  1012. }
  1013. data += b;
  1014. maxlen -= (b + 1); /* account for data++ above */
  1015. }
  1016. /* Up to here we were skipping encoded name */
  1017. /* Account for QTYPE and QCLASS fields */
  1018. if (maxlen < 4)
  1019. return -1;
  1020. return data - start + 2 + 2;
  1021. }
  1022. static int __decode_answer(const unsigned char *message, /* packet */
  1023. int offset,
  1024. int len, /* total packet len */
  1025. struct resolv_answer *a)
  1026. {
  1027. char temp[256];
  1028. int i;
  1029. DPRINTF("decode_answer(start): off %d, len %d\n", offset, len);
  1030. i = __decode_dotted(message, offset, len, temp, sizeof(temp));
  1031. if (i < 0)
  1032. return i;
  1033. message += offset + i;
  1034. len -= i + RRFIXEDSZ + offset;
  1035. if (len < 0) {
  1036. DPRINTF("decode_answer: off %d, len %d, i %d\n", offset, len, i);
  1037. return len;
  1038. }
  1039. /* TODO: what if strdup fails? */
  1040. a->dotted = strdup(temp);
  1041. a->atype = (message[0] << 8) | message[1];
  1042. message += 2;
  1043. a->aclass = (message[0] << 8) | message[1];
  1044. message += 2;
  1045. a->ttl = (message[0] << 24) |
  1046. (message[1] << 16) | (message[2] << 8) | (message[3] << 0);
  1047. message += 4;
  1048. a->rdlength = (message[0] << 8) | message[1];
  1049. message += 2;
  1050. a->rdata = message;
  1051. a->rdoffset = offset + i + RRFIXEDSZ;
  1052. DPRINTF("i=%d,rdlength=%d\n", i, a->rdlength);
  1053. if (len < a->rdlength)
  1054. return -1;
  1055. return i + RRFIXEDSZ + a->rdlength;
  1056. }
  1057. /* On entry:
  1058. * a.buf(len) = auxiliary buffer for IP addresses after first one
  1059. * a.add_count = how many additional addresses are there already
  1060. * outpacket = where to save ptr to raw packet? can be NULL
  1061. * On exit:
  1062. * ret < 0: error, all other data is not valid
  1063. * ret >= 0: length of reply packet
  1064. * a.add_count & a.buf: updated
  1065. * a.rdlength: length of addresses (4 bytes for IPv4)
  1066. * *outpacket: updated (packet is malloced, you need to free it)
  1067. * a.rdata: points into *outpacket to 1st IP addr
  1068. * NB: don't pass outpacket == NULL if you need to use a.rdata!
  1069. * a.atype: type of query?
  1070. * a.dotted: which name we _actually_ used. May contain search domains
  1071. * appended. (why the filed is called "dotted" I have no idea)
  1072. * This is a malloced string. May be NULL because strdup failed.
  1073. */
  1074. int attribute_hidden __dns_lookup(const char *name,
  1075. int type,
  1076. unsigned char **outpacket,
  1077. struct resolv_answer *a)
  1078. {
  1079. /* Protected by __resolv_lock: */
  1080. static int last_ns_num = 0;
  1081. static uint16_t last_id = 1;
  1082. int i, j, fd, rc;
  1083. int packet_len;
  1084. int name_len;
  1085. #ifdef USE_SELECT
  1086. struct timeval tv;
  1087. fd_set fds;
  1088. #else
  1089. struct pollfd fds;
  1090. #endif
  1091. struct resolv_header h;
  1092. struct resolv_question q;
  1093. struct resolv_answer ma;
  1094. bool first_answer = 1;
  1095. int retries_left;
  1096. unsigned char *packet = malloc(PACKETSZ);
  1097. char *lookup;
  1098. int variant = -1; /* search domain to append, -1: none */
  1099. int local_ns_num = -1; /* Nth server to use */
  1100. int local_id = local_id; /* for compiler */
  1101. int sdomains;
  1102. bool ends_with_dot;
  1103. sockaddr46_t sa;
  1104. fd = -1;
  1105. lookup = NULL;
  1106. name_len = strlen(name);
  1107. if ((unsigned)name_len >= MAXDNAME - MAXLEN_searchdomain - 2)
  1108. goto fail; /* paranoia */
  1109. lookup = malloc(name_len + 1/*for '.'*/ + MAXLEN_searchdomain + 1);
  1110. if (!packet || !lookup || !name[0])
  1111. goto fail;
  1112. ends_with_dot = (name[name_len - 1] == '.');
  1113. /* no strcpy! paranoia, user might change name[] under us */
  1114. memcpy(lookup, name, name_len);
  1115. DPRINTF("Looking up type %d answer for '%s'\n", type, name);
  1116. retries_left = 0; /* for compiler */
  1117. do {
  1118. int pos;
  1119. unsigned reply_timeout;
  1120. if (fd != -1) {
  1121. close(fd);
  1122. fd = -1;
  1123. }
  1124. /* Mess with globals while under lock */
  1125. /* NB: even data *pointed to* by globals may vanish
  1126. * outside the locks. We should assume any and all
  1127. * globals can completely change between locked
  1128. * code regions. OTOH, this is rare, so we don't need
  1129. * to handle it "nicely" (do not skip servers,
  1130. * search domains, etc), we only need to ensure
  1131. * we do not SEGV, use freed+overwritten data
  1132. * or do other Really Bad Things. */
  1133. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  1134. __open_nameservers();
  1135. sdomains = __searchdomains;
  1136. lookup[name_len] = '\0';
  1137. if ((unsigned)variant < sdomains) {
  1138. /* lookup is name_len + 1 + MAXLEN_searchdomain + 1 long */
  1139. /* __searchdomain[] is not bigger than MAXLEN_searchdomain */
  1140. lookup[name_len] = '.';
  1141. strcpy(&lookup[name_len + 1], __searchdomain[variant]);
  1142. }
  1143. /* first time? pick starting server etc */
  1144. if (local_ns_num < 0) {
  1145. local_id = last_id;
  1146. /*TODO: implement /etc/resolv.conf's "options rotate"
  1147. (a.k.a. RES_ROTATE bit in _res.options)
  1148. local_ns_num = 0;
  1149. if (_res.options & RES_ROTATE) */
  1150. local_ns_num = last_ns_num;
  1151. /*TODO: use _res.retry */
  1152. retries_left = __nameservers * RES_DFLRETRY;
  1153. }
  1154. retries_left--;
  1155. if (local_ns_num >= __nameservers)
  1156. local_ns_num = 0;
  1157. local_id++;
  1158. local_id &= 0xffff;
  1159. /* write new values back while still under lock */
  1160. last_id = local_id;
  1161. last_ns_num = local_ns_num;
  1162. /* struct copy */
  1163. /* can't just take a pointer, __nameserver[x]
  1164. * is not safe to use outside of locks */
  1165. sa = __nameserver[local_ns_num];
  1166. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  1167. memset(packet, 0, PACKETSZ);
  1168. memset(&h, 0, sizeof(h));
  1169. /* encode header */
  1170. h.id = local_id;
  1171. h.qdcount = 1;
  1172. h.rd = 1;
  1173. DPRINTF("encoding header\n", h.rd);
  1174. i = __encode_header(&h, packet, PACKETSZ);
  1175. if (i < 0)
  1176. goto fail;
  1177. /* encode question */
  1178. DPRINTF("lookup name: %s\n", lookup);
  1179. q.dotted = lookup;
  1180. q.qtype = type;
  1181. q.qclass = C_IN; /* CLASS_IN */
  1182. j = __encode_question(&q, packet+i, PACKETSZ-i);
  1183. if (j < 0)
  1184. goto fail;
  1185. packet_len = i + j;
  1186. /* send packet */
  1187. DPRINTF("On try %d, sending query to port %d\n",
  1188. retries_left, NAMESERVER_PORT);
  1189. fd = socket(sa.sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
  1190. if (fd < 0) /* paranoia */
  1191. goto try_next_server;
  1192. rc = connect(fd, &sa.sa, sizeof(sa));
  1193. if (rc < 0) {
  1194. /*if (errno == ENETUNREACH) { */
  1195. /* routing error, presume not transient */
  1196. goto try_next_server;
  1197. /*} */
  1198. /*For example, what transient error this can be? Can't think of any */
  1199. /* retry */
  1200. /*continue; */
  1201. }
  1202. DPRINTF("Xmit packet len:%d id:%d qr:%d\n", packet_len, h.id, h.qr);
  1203. /* no error check - if it fails, we time out on recv */
  1204. send(fd, packet, packet_len, 0);
  1205. #ifdef USE_SELECT
  1206. /*TODO: use _res.retrans*/
  1207. reply_timeout = RES_TIMEOUT;
  1208. wait_again:
  1209. FD_ZERO(&fds);
  1210. FD_SET(fd, &fds);
  1211. tv.tv_sec = reply_timeout;
  1212. tv.tv_usec = 0;
  1213. if (select(fd + 1, &fds, NULL, NULL, &tv) <= 0) {
  1214. DPRINTF("Timeout\n");
  1215. /* timed out, so retry send and receive
  1216. * to next nameserver */
  1217. goto try_next_server;
  1218. }
  1219. reply_timeout--;
  1220. #else
  1221. reply_timeout = RES_TIMEOUT * 1000;
  1222. wait_again:
  1223. fds.fd = fd;
  1224. fds.events = POLLIN;
  1225. if (poll(&fds, 1, reply_timeout) <= 0) {
  1226. DPRINTF("Timeout\n");
  1227. /* timed out, so retry send and receive
  1228. * to next nameserver */
  1229. goto try_next_server;
  1230. }
  1231. /*TODO: better timeout accounting?*/
  1232. reply_timeout -= 1000;
  1233. #endif
  1234. /* vda: a bogus response seen in real world (caused SEGV in uclibc):
  1235. * "ping www.google.com" sending AAAA query and getting
  1236. * response with one answer... with answer part missing!
  1237. * Fixed by thorough checks for not going past the packet's end.
  1238. */
  1239. #ifdef DEBUG
  1240. {
  1241. 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";
  1242. 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";
  1243. pos = memcmp(packet + 2, test_query + 2, 30);
  1244. packet_len = recv(fd, packet, PACKETSZ, MSG_DONTWAIT);
  1245. if (pos == 0) {
  1246. packet_len = 32;
  1247. memcpy(packet + 2, test_respn + 2, 30);
  1248. }
  1249. }
  1250. #else
  1251. packet_len = recv(fd, packet, PACKETSZ, MSG_DONTWAIT);
  1252. #endif
  1253. if (packet_len < HFIXEDSZ) {
  1254. /* too short!
  1255. * it's just a bogus packet from somewhere */
  1256. bogus_packet:
  1257. if (reply_timeout)
  1258. goto wait_again;
  1259. goto try_next_server;
  1260. }
  1261. __decode_header(packet, &h);
  1262. DPRINTF("len:%d id:%d qr:%d\n", packet_len, h.id, h.qr);
  1263. if (h.id != local_id || !h.qr) {
  1264. /* unsolicited */
  1265. goto bogus_packet;
  1266. }
  1267. DPRINTF("Got response (i think)!\n");
  1268. DPRINTF("qrcount=%d,ancount=%d,nscount=%d,arcount=%d\n",
  1269. h.qdcount, h.ancount, h.nscount, h.arcount);
  1270. DPRINTF("opcode=%d,aa=%d,tc=%d,rd=%d,ra=%d,rcode=%d\n",
  1271. h.opcode, h.aa, h.tc, h.rd, h.ra, h.rcode);
  1272. /* bug 660 says we treat negative response as an error
  1273. * and retry, which is, eh, an error. :)
  1274. * We were incurring long delays because of this. */
  1275. if (h.rcode == NXDOMAIN) {
  1276. /* if possible, try next search domain */
  1277. if (!ends_with_dot) {
  1278. DPRINTF("variant:%d sdomains:%d\n", variant, sdomains);
  1279. if (variant < sdomains - 1) {
  1280. /* next search domain */
  1281. variant++;
  1282. continue;
  1283. }
  1284. /* no more search domains to try */
  1285. }
  1286. /* dont loop, this is "no such host" situation */
  1287. h_errno = HOST_NOT_FOUND;
  1288. goto fail1;
  1289. }
  1290. /* Insert other non-fatal errors here, which do not warrant
  1291. * switching to next nameserver */
  1292. /* Strange error, assuming this nameserver is feeling bad */
  1293. if (h.rcode != 0)
  1294. goto try_next_server;
  1295. /* Code below won't work correctly with h.ancount == 0, so... */
  1296. if (h.ancount <= 0) {
  1297. h_errno = NO_DATA; /* [is this correct code to check for?] */
  1298. goto fail1;
  1299. }
  1300. pos = HFIXEDSZ;
  1301. for (j = 0; j < h.qdcount; j++) {
  1302. DPRINTF("Skipping question %d at %d\n", j, pos);
  1303. i = __length_question(packet + pos, packet_len - pos);
  1304. if (i < 0) {
  1305. DPRINTF("Packet'question section "
  1306. "is truncated, trying next server\n");
  1307. goto try_next_server;
  1308. }
  1309. pos += i;
  1310. DPRINTF("Length of question %d is %d\n", j, i);
  1311. }
  1312. DPRINTF("Decoding answer at pos %d\n", pos);
  1313. first_answer = 1;
  1314. for (j = 0; j < h.ancount; j++) {
  1315. i = __decode_answer(packet, pos, packet_len, &ma);
  1316. if (i < 0) {
  1317. DPRINTF("failed decode %d\n", i);
  1318. /* If the message was truncated but we have
  1319. * decoded some answers, pretend it's OK */
  1320. if (j && h.tc)
  1321. break;
  1322. goto try_next_server;
  1323. }
  1324. pos += i;
  1325. if (first_answer) {
  1326. ma.buf = a->buf;
  1327. ma.buflen = a->buflen;
  1328. ma.add_count = a->add_count;
  1329. memcpy(a, &ma, sizeof(ma));
  1330. if (a->atype != T_SIG && (NULL == a->buf || (type != T_A && type != T_AAAA)))
  1331. break;
  1332. if (a->atype != type) {
  1333. free(a->dotted);
  1334. continue;
  1335. }
  1336. a->add_count = h.ancount - j - 1;
  1337. if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen)
  1338. break;
  1339. a->add_count = 0;
  1340. first_answer = 0;
  1341. } else {
  1342. free(ma.dotted);
  1343. if (ma.atype != type)
  1344. continue;
  1345. if (a->rdlength != ma.rdlength) {
  1346. free(a->dotted);
  1347. DPRINTF("Answer address len(%u) differs from original(%u)\n",
  1348. ma.rdlength, a->rdlength);
  1349. goto try_next_server;
  1350. }
  1351. memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength);
  1352. ++a->add_count;
  1353. }
  1354. }
  1355. /* Success! */
  1356. DPRINTF("Answer name = |%s|\n", a->dotted);
  1357. DPRINTF("Answer type = |%d|\n", a->atype);
  1358. if (fd != -1)
  1359. close(fd);
  1360. if (outpacket)
  1361. *outpacket = packet;
  1362. else
  1363. free(packet);
  1364. free(lookup);
  1365. return packet_len;
  1366. try_next_server:
  1367. /* Try next nameserver */
  1368. local_ns_num++;
  1369. variant = -1;
  1370. } while (retries_left > 0);
  1371. fail:
  1372. h_errno = NETDB_INTERNAL;
  1373. fail1:
  1374. if (fd != -1)
  1375. close(fd);
  1376. free(lookup);
  1377. free(packet);
  1378. return -1;
  1379. }
  1380. #endif
  1381. #ifdef L_read_etc_hosts_r
  1382. FILE * __open_etc_hosts(void)
  1383. {
  1384. FILE * fp;
  1385. if ((fp = fopen("/etc/hosts", "r")) == NULL) {
  1386. fp = fopen("/etc/config/hosts", "r");
  1387. }
  1388. return fp;
  1389. }
  1390. int attribute_hidden __read_etc_hosts_r(
  1391. FILE * fp,
  1392. const char *name,
  1393. int type,
  1394. enum etc_hosts_action action,
  1395. struct hostent *result_buf,
  1396. char *buf, size_t buflen,
  1397. struct hostent **result,
  1398. int *h_errnop)
  1399. {
  1400. struct in_addr **addr_list = NULL;
  1401. struct in_addr *in = NULL;
  1402. char *cp, **alias;
  1403. int aliases, i, ret = HOST_NOT_FOUND;
  1404. *h_errnop = NETDB_INTERNAL;
  1405. /* make sure pointer is aligned */
  1406. i = ALIGN_BUFFER_OFFSET(buf);
  1407. buf += i;
  1408. buflen -= i;
  1409. /* Layout in buf:
  1410. * char *alias[ALIAS_DIM];
  1411. * struct in[6]_addr* addr_list[2];
  1412. * struct in[6]_addr* in;
  1413. * char line_buffer[80+];
  1414. */
  1415. #define in6 ((struct in6_addr *)in)
  1416. alias = (char **)buf;
  1417. buf += sizeof(char **) * ALIAS_DIM;
  1418. buflen -= sizeof(char **) * ALIAS_DIM;
  1419. if ((ssize_t)buflen < 0)
  1420. return ERANGE;
  1421. if (action != GETHOSTENT) {
  1422. addr_list = (struct in_addr**)buf;
  1423. buf += sizeof(*addr_list) * 2;
  1424. buflen -= sizeof(*addr_list) * 2;
  1425. in = (struct in_addr*)buf;
  1426. #ifndef __UCLIBC_HAS_IPV6__
  1427. buf += sizeof(*in);
  1428. buflen -= sizeof(*in);
  1429. #else
  1430. buf += sizeof(*in6);
  1431. buflen -= sizeof(*in6);
  1432. #endif
  1433. if ((ssize_t)buflen < 80)
  1434. return ERANGE;
  1435. fp = __open_etc_hosts();
  1436. if (fp == NULL) {
  1437. *result = NULL;
  1438. return errno;
  1439. }
  1440. addr_list[0] = in;
  1441. addr_list[1] = NULL;
  1442. }
  1443. *h_errnop = HOST_NOT_FOUND;
  1444. while (fgets(buf, buflen, fp)) {
  1445. *strchrnul(buf, '#') = '\0';
  1446. DPRINTF("Looking at: %s\n", buf);
  1447. aliases = 0;
  1448. cp = buf;
  1449. while (*cp) {
  1450. while (*cp && isspace(*cp))
  1451. *cp++ = '\0';
  1452. if (!*cp)
  1453. break;
  1454. if (aliases < (2 + MAX_ALIASES))
  1455. alias[aliases++] = cp;
  1456. while (*cp && !isspace(*cp))
  1457. cp++;
  1458. }
  1459. alias[aliases] = NULL;
  1460. if (aliases < 2)
  1461. continue; /* syntax error really */
  1462. if (action == GETHOSTENT) {
  1463. /* Return whatever the next entry happens to be. */
  1464. break;
  1465. }
  1466. if (action == GET_HOSTS_BYADDR) {
  1467. if (strcmp(name, alias[0]) != 0)
  1468. continue;
  1469. } else {
  1470. /* GET_HOSTS_BYNAME */
  1471. for (i = 1; i < aliases; i++)
  1472. if (strcasecmp(name, alias[i]) == 0)
  1473. goto found;
  1474. continue;
  1475. found: ;
  1476. }
  1477. if (0) /* nothing */;
  1478. #ifdef __UCLIBC_HAS_IPV4__
  1479. else if (type == AF_INET && inet_pton(AF_INET, alias[0], in) > 0) {
  1480. DPRINTF("Found INET\n");
  1481. result_buf->h_addrtype = AF_INET;
  1482. result_buf->h_length = sizeof(*in);
  1483. result_buf->h_name = alias[1];
  1484. result_buf->h_addr_list = (char**) addr_list;
  1485. result_buf->h_aliases = alias + 2;
  1486. *result = result_buf;
  1487. ret = NETDB_SUCCESS;
  1488. }
  1489. #endif
  1490. #ifdef __UCLIBC_HAS_IPV6__
  1491. else if (type == AF_INET6 && inet_pton(AF_INET6, alias[0], in6) > 0) {
  1492. DPRINTF("Found INET6\n");
  1493. result_buf->h_addrtype = AF_INET6;
  1494. result_buf->h_length = sizeof(*in6);
  1495. result_buf->h_name = alias[1];
  1496. result_buf->h_addr_list = (char**) addr_list;
  1497. result_buf->h_aliases = alias + 2;
  1498. *result = result_buf;
  1499. ret = NETDB_SUCCESS;
  1500. }
  1501. #endif
  1502. else {
  1503. /* continue parsing in the hope the user has multiple
  1504. * host types listed in the database like so:
  1505. * <ipv4 addr> host
  1506. * <ipv6 addr> host
  1507. * If looking for an IPv6 addr, don't bail when we got the IPv4
  1508. */
  1509. DPRINTF("Error: Found host but diff network type\n");
  1510. /* NB: gethostbyname2_r depends on this feature
  1511. * to avoid looking for IPv6 addr of "localhost" etc */
  1512. ret = TRY_AGAIN;
  1513. continue;
  1514. }
  1515. break;
  1516. }
  1517. if (action != GETHOSTENT)
  1518. fclose(fp);
  1519. return ret;
  1520. #undef in6
  1521. }
  1522. #endif
  1523. #ifdef L_get_hosts_byname_r
  1524. int attribute_hidden __get_hosts_byname_r(const char *name,
  1525. int type,
  1526. struct hostent *result_buf,
  1527. char *buf,
  1528. size_t buflen,
  1529. struct hostent **result,
  1530. int *h_errnop)
  1531. {
  1532. return __read_etc_hosts_r(NULL, name, type, GET_HOSTS_BYNAME,
  1533. result_buf, buf, buflen, result, h_errnop);
  1534. }
  1535. #endif
  1536. #ifdef L_get_hosts_byaddr_r
  1537. int attribute_hidden __get_hosts_byaddr_r(const char *addr,
  1538. int len,
  1539. int type,
  1540. struct hostent *result_buf,
  1541. char *buf,
  1542. size_t buflen,
  1543. struct hostent **result,
  1544. int *h_errnop)
  1545. {
  1546. #ifndef __UCLIBC_HAS_IPV6__
  1547. char ipaddr[INET_ADDRSTRLEN];
  1548. #else
  1549. char ipaddr[INET6_ADDRSTRLEN];
  1550. #endif
  1551. switch (type) {
  1552. #ifdef __UCLIBC_HAS_IPV4__
  1553. case AF_INET:
  1554. if (len != sizeof(struct in_addr))
  1555. return 0;
  1556. break;
  1557. #endif
  1558. #ifdef __UCLIBC_HAS_IPV6__
  1559. case AF_INET6:
  1560. if (len != sizeof(struct in6_addr))
  1561. return 0;
  1562. break;
  1563. #endif
  1564. default:
  1565. return 0;
  1566. }
  1567. inet_ntop(type, addr, ipaddr, sizeof(ipaddr));
  1568. return __read_etc_hosts_r(NULL, ipaddr, type, GET_HOSTS_BYADDR,
  1569. result_buf, buf, buflen, result, h_errnop);
  1570. }
  1571. #endif
  1572. #ifdef L_getnameinfo
  1573. int getnameinfo(const struct sockaddr *sa,
  1574. socklen_t addrlen,
  1575. char *host,
  1576. socklen_t hostlen,
  1577. char *serv,
  1578. socklen_t servlen,
  1579. unsigned flags)
  1580. {
  1581. int serrno = errno;
  1582. unsigned ok;
  1583. struct hostent *h = NULL;
  1584. char domain[256];
  1585. if (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|NI_NAMEREQD|NI_DGRAM))
  1586. return EAI_BADFLAGS;
  1587. if (sa == NULL || addrlen < sizeof(sa_family_t))
  1588. return EAI_FAMILY;
  1589. ok = sa->sa_family;
  1590. if (ok == AF_LOCAL) /* valid */;
  1591. #ifdef __UCLIBC_HAS_IPV4__
  1592. else if (ok == AF_INET) {
  1593. if (addrlen < sizeof(struct sockaddr_in))
  1594. return EAI_FAMILY;
  1595. }
  1596. #endif
  1597. #ifdef __UCLIBC_HAS_IPV6__
  1598. else if (ok == AF_INET6) {
  1599. if (addrlen < sizeof(struct sockaddr_in6))
  1600. return EAI_FAMILY;
  1601. }
  1602. #endif
  1603. else
  1604. return EAI_FAMILY;
  1605. ok = 0;
  1606. if (host != NULL && hostlen > 0)
  1607. switch (sa->sa_family) {
  1608. case AF_INET:
  1609. #ifdef __UCLIBC_HAS_IPV6__
  1610. case AF_INET6:
  1611. #endif
  1612. if (!(flags & NI_NUMERICHOST)) {
  1613. if (0) /* nothing */;
  1614. #ifdef __UCLIBC_HAS_IPV6__
  1615. else if (sa->sa_family == AF_INET6)
  1616. h = gethostbyaddr((const void *)
  1617. &(((const struct sockaddr_in6 *) sa)->sin6_addr),
  1618. sizeof(struct in6_addr), AF_INET6);
  1619. #endif
  1620. #ifdef __UCLIBC_HAS_IPV4__
  1621. else
  1622. h = gethostbyaddr((const void *)
  1623. &(((const struct sockaddr_in *)sa)->sin_addr),
  1624. sizeof(struct in_addr), AF_INET);
  1625. #endif
  1626. if (h) {
  1627. char *c;
  1628. #undef min
  1629. #define min(x,y) (((x) > (y)) ? (y) : (x))
  1630. if ((flags & NI_NOFQDN)
  1631. && (getdomainname(domain, sizeof(domain)) == 0)
  1632. && (c = strstr(h->h_name, domain)) != NULL
  1633. && (c != h->h_name) && (*(--c) == '.')
  1634. ) {
  1635. strncpy(host, h->h_name,
  1636. min(hostlen, (size_t) (c - h->h_name)));
  1637. host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0';
  1638. } else {
  1639. strncpy(host, h->h_name, hostlen);
  1640. }
  1641. ok = 1;
  1642. #undef min
  1643. }
  1644. }
  1645. if (!ok) {
  1646. const char *c = NULL;
  1647. if (flags & NI_NAMEREQD) {
  1648. errno = serrno;
  1649. return EAI_NONAME;
  1650. }
  1651. if (0) /* nothing */;
  1652. #ifdef __UCLIBC_HAS_IPV6__
  1653. else if (sa->sa_family == AF_INET6) {
  1654. const struct sockaddr_in6 *sin6p;
  1655. sin6p = (const struct sockaddr_in6 *) sa;
  1656. c = inet_ntop(AF_INET6,
  1657. (const void *) &sin6p->sin6_addr,
  1658. host, hostlen);
  1659. #if 0
  1660. /* Does scope id need to be supported? */
  1661. uint32_t scopeid;
  1662. scopeid = sin6p->sin6_scope_id;
  1663. if (scopeid != 0) {
  1664. /* Buffer is >= IFNAMSIZ+1. */
  1665. char scopebuf[IFNAMSIZ + 1];
  1666. char *scopeptr;
  1667. int ni_numericscope = 0;
  1668. size_t real_hostlen = strnlen(host, hostlen);
  1669. size_t scopelen = 0;
  1670. scopebuf[0] = SCOPE_DELIMITER;
  1671. scopebuf[1] = '\0';
  1672. scopeptr = &scopebuf[1];
  1673. if (IN6_IS_ADDR_LINKLOCAL(&sin6p->sin6_addr)
  1674. || IN6_IS_ADDR_MC_LINKLOCAL(&sin6p->sin6_addr)) {
  1675. if (if_indextoname(scopeid, scopeptr) == NULL)
  1676. ++ni_numericscope;
  1677. else
  1678. scopelen = strlen(scopebuf);
  1679. } else {
  1680. ++ni_numericscope;
  1681. }
  1682. if (ni_numericscope)
  1683. scopelen = 1 + snprintf(scopeptr,
  1684. (scopebuf
  1685. + sizeof scopebuf
  1686. - scopeptr),
  1687. "%u", scopeid);
  1688. if (real_hostlen + scopelen + 1 > hostlen)
  1689. return EAI_SYSTEM;
  1690. memcpy(host + real_hostlen, scopebuf, scopelen + 1);
  1691. }
  1692. #endif
  1693. }
  1694. #endif /* __UCLIBC_HAS_IPV6__ */
  1695. #if defined __UCLIBC_HAS_IPV4__
  1696. else {
  1697. c = inet_ntop(AF_INET, (const void *)
  1698. &(((const struct sockaddr_in *) sa)->sin_addr),
  1699. host, hostlen);
  1700. }
  1701. #endif
  1702. if (c == NULL) {
  1703. errno = serrno;
  1704. return EAI_SYSTEM;
  1705. }
  1706. ok = 1;
  1707. }
  1708. break;
  1709. case AF_LOCAL:
  1710. if (!(flags & NI_NUMERICHOST)) {
  1711. struct utsname utsname;
  1712. if (!uname(&utsname)) {
  1713. strncpy(host, utsname.nodename, hostlen);
  1714. break;
  1715. };
  1716. };
  1717. if (flags & NI_NAMEREQD) {
  1718. errno = serrno;
  1719. return EAI_NONAME;
  1720. }
  1721. strncpy(host, "localhost", hostlen);
  1722. break;
  1723. /* Already checked above
  1724. default:
  1725. return EAI_FAMILY;
  1726. */
  1727. }
  1728. if (serv && (servlen > 0)) {
  1729. if (sa->sa_family == AF_LOCAL) {
  1730. strncpy(serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
  1731. } else { /* AF_INET || AF_INET6 */
  1732. if (!(flags & NI_NUMERICSERV)) {
  1733. struct servent *s;
  1734. s = getservbyport(((const struct sockaddr_in *) sa)->sin_port,
  1735. ((flags & NI_DGRAM) ? "udp" : "tcp"));
  1736. if (s) {
  1737. strncpy(serv, s->s_name, servlen);
  1738. goto DONE;
  1739. }
  1740. }
  1741. snprintf(serv, servlen, "%d",
  1742. ntohs(((const struct sockaddr_in *) sa)->sin_port));
  1743. }
  1744. }
  1745. DONE:
  1746. if (host && (hostlen > 0))
  1747. host[hostlen-1] = 0;
  1748. if (serv && (servlen > 0))
  1749. serv[servlen-1] = 0;
  1750. errno = serrno;
  1751. return 0;
  1752. }
  1753. libc_hidden_def(getnameinfo)
  1754. #endif
  1755. #ifdef L_gethostbyname_r
  1756. /* Bug 671 says:
  1757. * "uClibc resolver's gethostbyname does not return the requested name
  1758. * as an alias, but instead returns the canonical name. glibc's
  1759. * gethostbyname has a similar bug where it returns the requested name
  1760. * with the search domain name appended (to make a FQDN) as an alias,
  1761. * but not the original name itself. Both contradict POSIX, which says
  1762. * that the name argument passed to gethostbyname must be in the alias list"
  1763. * This is fixed now, and we differ from glibc:
  1764. *
  1765. * $ ./gethostbyname_uclibc wer.google.com
  1766. * h_name:'c13-ss-2-lb.cnet.com'
  1767. * h_length:4
  1768. * h_addrtype:2 AF_INET
  1769. * alias:'wer.google.com' <===
  1770. * addr: 0x4174efd8 '216.239.116.65'
  1771. *
  1772. * $ ./gethostbyname_glibc wer.google.com
  1773. * h_name:'c13-ss-2-lb.cnet.com'
  1774. * h_length:4
  1775. * h_addrtype:2 AF_INET
  1776. * alias:'wer.google.com.com' <===
  1777. * addr:'216.239.116.65'
  1778. *
  1779. * When examples were run, /etc/resolv.conf contained "search com" line.
  1780. */
  1781. int gethostbyname_r(const char *name,
  1782. struct hostent *result_buf,
  1783. char *buf,
  1784. size_t buflen,
  1785. struct hostent **result,
  1786. int *h_errnop)
  1787. {
  1788. struct in_addr **addr_list;
  1789. char **alias;
  1790. char *alias0;
  1791. unsigned char *packet;
  1792. struct resolv_answer a;
  1793. int i;
  1794. int packet_len;
  1795. int wrong_af = 0;
  1796. *result = NULL;
  1797. if (!name)
  1798. return EINVAL;
  1799. /* do /etc/hosts first */
  1800. {
  1801. int old_errno = errno; /* save the old errno and reset errno */
  1802. __set_errno(0); /* to check for missing /etc/hosts. */
  1803. i = __get_hosts_byname_r(name, AF_INET, result_buf,
  1804. buf, buflen, result, h_errnop);
  1805. if (i == NETDB_SUCCESS) {
  1806. __set_errno(old_errno);
  1807. return i;
  1808. }
  1809. switch (*h_errnop) {
  1810. case HOST_NOT_FOUND:
  1811. wrong_af = (i == TRY_AGAIN);
  1812. case NO_ADDRESS:
  1813. break;
  1814. case NETDB_INTERNAL:
  1815. if (errno == ENOENT) {
  1816. break;
  1817. }
  1818. /* else fall through */
  1819. default:
  1820. return i;
  1821. }
  1822. __set_errno(old_errno);
  1823. }
  1824. DPRINTF("Nothing found in /etc/hosts\n");
  1825. *h_errnop = NETDB_INTERNAL;
  1826. /* prepare future h_aliases[0] */
  1827. i = strlen(name) + 1;
  1828. if ((ssize_t)buflen <= i)
  1829. return ERANGE;
  1830. memcpy(buf, name, i); /* paranoia: name might change */
  1831. alias0 = buf;
  1832. buf += i;
  1833. buflen -= i;
  1834. /* make sure pointer is aligned */
  1835. i = ALIGN_BUFFER_OFFSET(buf);
  1836. buf += i;
  1837. buflen -= i;
  1838. /* Layout in buf:
  1839. * char *alias[2];
  1840. * struct in_addr* addr_list[NN+1];
  1841. * struct in_addr* in[NN];
  1842. */
  1843. alias = (char **)buf;
  1844. buf += sizeof(alias[0]) * 2;
  1845. buflen -= sizeof(alias[0]) * 2;
  1846. addr_list = (struct in_addr **)buf;
  1847. /* buflen may be < 0, must do signed compare */
  1848. if ((ssize_t)buflen < 256)
  1849. return ERANGE;
  1850. /* we store only one "alias" - the name itself */
  1851. #ifdef __UCLIBC_MJN3_ONLY__
  1852. #warning TODO -- generate the full list
  1853. #endif
  1854. alias[0] = alias0;
  1855. alias[1] = NULL;
  1856. /* maybe it is already an address? */
  1857. {
  1858. struct in_addr *in = (struct in_addr *)(buf + sizeof(addr_list[0]) * 2);
  1859. if (inet_aton(name, in)) {
  1860. addr_list[0] = in;
  1861. addr_list[1] = NULL;
  1862. result_buf->h_name = alias0;
  1863. result_buf->h_aliases = alias;
  1864. result_buf->h_addrtype = AF_INET;
  1865. result_buf->h_length = sizeof(struct in_addr);
  1866. result_buf->h_addr_list = (char **) addr_list;
  1867. *result = result_buf;
  1868. *h_errnop = NETDB_SUCCESS;
  1869. return NETDB_SUCCESS;
  1870. }
  1871. }
  1872. /* what if /etc/hosts has it but it's not IPv4?
  1873. * F.e. "::1 localhost6". We don't do DNS query for such hosts -
  1874. * "ping localhost6" should be fast even if DNS server is down! */
  1875. if (wrong_af) {
  1876. *h_errnop = HOST_NOT_FOUND;
  1877. return TRY_AGAIN;
  1878. }
  1879. /* talk to DNS servers */
  1880. a.buf = buf;
  1881. /* take into account that at least one address will be there,
  1882. * we'll need space of one in_addr + two addr_list[] elems */
  1883. a.buflen = buflen - ((sizeof(addr_list[0]) * 2 + sizeof(struct in_addr)));
  1884. a.add_count = 0;
  1885. packet_len = __dns_lookup(name, T_A, &packet, &a);
  1886. if (packet_len < 0) {
  1887. *h_errnop = HOST_NOT_FOUND;
  1888. DPRINTF("__dns_lookup returned < 0\n");
  1889. return TRY_AGAIN;
  1890. }
  1891. if (a.atype == T_A) { /* ADDRESS */
  1892. /* we need space for addr_list[] and one IPv4 address */
  1893. /* + 1 accounting for 1st addr (it's in a.rdata),
  1894. * another + 1 for NULL in last addr_list[]: */
  1895. int need_bytes = sizeof(addr_list[0]) * (a.add_count + 1 + 1)
  1896. /* for 1st addr (it's in a.rdata): */
  1897. + sizeof(struct in_addr);
  1898. /* how many bytes will 2nd and following addresses take? */
  1899. int ips_len = a.add_count * a.rdlength;
  1900. buflen -= (need_bytes + ips_len);
  1901. if ((ssize_t)buflen < 0) {
  1902. DPRINTF("buffer too small for all addresses\n");
  1903. /* *h_errnop = NETDB_INTERNAL; - already is */
  1904. i = ERANGE;
  1905. goto free_and_ret;
  1906. }
  1907. /* if there are additional addresses in buf,
  1908. * move them forward so that they are not destroyed */
  1909. DPRINTF("a.add_count:%d a.rdlength:%d a.rdata:%p\n", a.add_count, a.rdlength, a.rdata);
  1910. memmove(buf + need_bytes, buf, ips_len);
  1911. /* 1st address is in a.rdata, insert it */
  1912. buf += need_bytes - sizeof(struct in_addr);
  1913. memcpy(buf, a.rdata, sizeof(struct in_addr));
  1914. /* fill addr_list[] */
  1915. for (i = 0; i <= a.add_count; i++) {
  1916. addr_list[i] = (struct in_addr*)buf;
  1917. buf += sizeof(struct in_addr);
  1918. }
  1919. addr_list[i] = NULL;
  1920. /* if we have enough space, we can report "better" name
  1921. * (it may contain search domains attached by __dns_lookup,
  1922. * or CNAME of the host if it is different from the name
  1923. * we used to find it) */
  1924. if (a.dotted && buflen > strlen(a.dotted)) {
  1925. strcpy(buf, a.dotted);
  1926. alias0 = buf;
  1927. }
  1928. result_buf->h_name = alias0;
  1929. result_buf->h_aliases = alias;
  1930. result_buf->h_addrtype = AF_INET;
  1931. result_buf->h_length = sizeof(struct in_addr);
  1932. result_buf->h_addr_list = (char **) addr_list;
  1933. *result = result_buf;
  1934. *h_errnop = NETDB_SUCCESS;
  1935. i = NETDB_SUCCESS;
  1936. goto free_and_ret;
  1937. }
  1938. *h_errnop = HOST_NOT_FOUND;
  1939. i = TRY_AGAIN;
  1940. free_and_ret:
  1941. free(a.dotted);
  1942. free(packet);
  1943. return i;
  1944. }
  1945. libc_hidden_def(gethostbyname_r)
  1946. #endif
  1947. #ifdef L_gethostbyname2_r
  1948. int gethostbyname2_r(const char *name,
  1949. int family,
  1950. struct hostent *result_buf,
  1951. char *buf,
  1952. size_t buflen,
  1953. struct hostent **result,
  1954. int *h_errnop)
  1955. {
  1956. #ifndef __UCLIBC_HAS_IPV6__
  1957. return family == (AF_INET)
  1958. ? gethostbyname_r(name, result_buf, buf, buflen, result, h_errnop)
  1959. : HOST_NOT_FOUND;
  1960. #else
  1961. struct in6_addr *in;
  1962. struct in6_addr **addr_list;
  1963. unsigned char *packet;
  1964. struct resolv_answer a;
  1965. int i;
  1966. int nest = 0;
  1967. int wrong_af = 0;
  1968. if (family == AF_INET)
  1969. return gethostbyname_r(name, result_buf, buf, buflen, result, h_errnop);
  1970. *result = NULL;
  1971. if (family != AF_INET6)
  1972. return EINVAL;
  1973. if (!name)
  1974. return EINVAL;
  1975. /* do /etc/hosts first */
  1976. {
  1977. int old_errno = errno; /* Save the old errno and reset errno */
  1978. __set_errno(0); /* to check for missing /etc/hosts. */
  1979. i = __get_hosts_byname_r(name, AF_INET6 /*family*/, result_buf,
  1980. buf, buflen, result, h_errnop);
  1981. if (i == NETDB_SUCCESS) {
  1982. __set_errno(old_errno);
  1983. return i;
  1984. }
  1985. switch (*h_errnop) {
  1986. case HOST_NOT_FOUND:
  1987. wrong_af = (i == TRY_AGAIN);
  1988. case NO_ADDRESS:
  1989. break;
  1990. case NETDB_INTERNAL:
  1991. if (errno == ENOENT) {
  1992. break;
  1993. }
  1994. /* else fall through */
  1995. default:
  1996. return i;
  1997. }
  1998. __set_errno(old_errno);
  1999. }
  2000. DPRINTF("Nothing found in /etc/hosts\n");
  2001. *h_errnop = NETDB_INTERNAL;
  2002. /* make sure pointer is aligned */
  2003. i = ALIGN_BUFFER_OFFSET(buf);
  2004. buf += i;
  2005. buflen -= i;
  2006. /* Layout in buf:
  2007. * struct in6_addr* in;
  2008. * struct in6_addr* addr_list[2];
  2009. * char scratch_buf[256];
  2010. */
  2011. in = (struct in6_addr*)buf;
  2012. buf += sizeof(*in);
  2013. buflen -= sizeof(*in);
  2014. addr_list = (struct in6_addr**)buf;
  2015. buf += sizeof(*addr_list) * 2;
  2016. buflen -= sizeof(*addr_list) * 2;
  2017. if ((ssize_t)buflen < 256)
  2018. return ERANGE;
  2019. addr_list[0] = in;
  2020. addr_list[1] = NULL;
  2021. strncpy(buf, name, buflen);
  2022. buf[buflen] = '\0';
  2023. /* maybe it is already an address? */
  2024. if (inet_pton(AF_INET6, name, in)) {
  2025. result_buf->h_name = buf;
  2026. result_buf->h_addrtype = AF_INET6;
  2027. result_buf->h_length = sizeof(*in);
  2028. result_buf->h_addr_list = (char **) addr_list;
  2029. /* result_buf->h_aliases = ??? */
  2030. *result = result_buf;
  2031. *h_errnop = NETDB_SUCCESS;
  2032. return NETDB_SUCCESS;
  2033. }
  2034. /* what if /etc/hosts has it but it's not IPv6?
  2035. * F.e. "127.0.0.1 localhost". We don't do DNS query for such hosts -
  2036. * "ping localhost" should be fast even if DNS server is down! */
  2037. if (wrong_af) {
  2038. *h_errnop = HOST_NOT_FOUND;
  2039. return TRY_AGAIN;
  2040. }
  2041. /* talk to DNS servers */
  2042. /* TODO: why it's so different from gethostbyname_r (IPv4 case)? */
  2043. memset(&a, '\0', sizeof(a));
  2044. for (;;) {
  2045. int packet_len;
  2046. /* Hmm why we memset(a) to zeros only once? */
  2047. packet_len = __dns_lookup(buf, T_AAAA, &packet, &a);
  2048. if (packet_len < 0) {
  2049. *h_errnop = HOST_NOT_FOUND;
  2050. return TRY_AGAIN;
  2051. }
  2052. strncpy(buf, a.dotted, buflen);
  2053. free(a.dotted);
  2054. if (a.atype != T_CNAME)
  2055. break;
  2056. DPRINTF("Got a CNAME in gethostbyname()\n");
  2057. if (++nest > MAX_RECURSE) {
  2058. *h_errnop = NO_RECOVERY;
  2059. return -1;
  2060. }
  2061. i = __decode_dotted(packet, a.rdoffset, packet_len, buf, buflen);
  2062. free(packet);
  2063. if (i < 0) {
  2064. *h_errnop = NO_RECOVERY;
  2065. return -1;
  2066. }
  2067. }
  2068. if (a.atype == T_AAAA) { /* ADDRESS */
  2069. memcpy(in, a.rdata, sizeof(*in));
  2070. result_buf->h_name = buf;
  2071. result_buf->h_addrtype = AF_INET6;
  2072. result_buf->h_length = sizeof(*in);
  2073. result_buf->h_addr_list = (char **) addr_list;
  2074. /* result_buf->h_aliases = ??? */
  2075. free(packet);
  2076. *result = result_buf;
  2077. *h_errnop = NETDB_SUCCESS;
  2078. return NETDB_SUCCESS;
  2079. }
  2080. free(packet);
  2081. *h_errnop = HOST_NOT_FOUND;
  2082. return TRY_AGAIN;
  2083. #endif /* __UCLIBC_HAS_IPV6__ */
  2084. }
  2085. libc_hidden_def(gethostbyname2_r)
  2086. #endif
  2087. #ifdef L_gethostbyaddr_r
  2088. int gethostbyaddr_r(const void *addr, socklen_t addrlen,
  2089. int type,
  2090. struct hostent *result_buf,
  2091. char *buf, size_t buflen,
  2092. struct hostent **result,
  2093. int *h_errnop)
  2094. {
  2095. struct in_addr *in;
  2096. struct in_addr **addr_list;
  2097. char **alias;
  2098. unsigned char *packet;
  2099. struct resolv_answer a;
  2100. int i;
  2101. int packet_len;
  2102. int nest = 0;
  2103. *result = NULL;
  2104. if (!addr)
  2105. return EINVAL;
  2106. switch (type) {
  2107. #ifdef __UCLIBC_HAS_IPV4__
  2108. case AF_INET:
  2109. if (addrlen != sizeof(struct in_addr))
  2110. return EINVAL;
  2111. break;
  2112. #endif
  2113. #ifdef __UCLIBC_HAS_IPV6__
  2114. case AF_INET6:
  2115. if (addrlen != sizeof(struct in6_addr))
  2116. return EINVAL;
  2117. break;
  2118. #endif
  2119. default:
  2120. return EINVAL;
  2121. }
  2122. /* do /etc/hosts first */
  2123. i = __get_hosts_byaddr_r(addr, addrlen, type, result_buf,
  2124. buf, buflen, result, h_errnop);
  2125. if (i == 0)
  2126. return i;
  2127. switch (*h_errnop) {
  2128. case HOST_NOT_FOUND:
  2129. case NO_ADDRESS:
  2130. break;
  2131. default:
  2132. return i;
  2133. }
  2134. *h_errnop = NETDB_INTERNAL;
  2135. /* make sure pointer is aligned */
  2136. i = ALIGN_BUFFER_OFFSET(buf);
  2137. buf += i;
  2138. buflen -= i;
  2139. /* Layout in buf:
  2140. * char *alias[ALIAS_DIM];
  2141. * struct in[6]_addr* addr_list[2];
  2142. * struct in[6]_addr* in;
  2143. * char scratch_buffer[256+];
  2144. */
  2145. #define in6 ((struct in6_addr *)in)
  2146. alias = (char **)buf;
  2147. buf += sizeof(*alias) * ALIAS_DIM;
  2148. buflen -= sizeof(*alias) * ALIAS_DIM;
  2149. addr_list = (struct in_addr**)buf;
  2150. buf += sizeof(*addr_list) * 2;
  2151. buflen -= sizeof(*addr_list) * 2;
  2152. in = (struct in_addr*)buf;
  2153. #ifndef __UCLIBC_HAS_IPV6__
  2154. buf += sizeof(*in);
  2155. buflen -= sizeof(*in);
  2156. #else
  2157. buf += sizeof(*in6);
  2158. buflen -= sizeof(*in6);
  2159. #endif
  2160. if ((ssize_t)buflen < 256)
  2161. return ERANGE;
  2162. alias[0] = buf;
  2163. alias[1] = NULL;
  2164. addr_list[0] = in;
  2165. addr_list[1] = NULL;
  2166. memcpy(&in, addr, addrlen);
  2167. if (0) /* nothing */;
  2168. #ifdef __UCLIBC_HAS_IPV4__
  2169. else IF_HAS_BOTH(if (type == AF_INET)) {
  2170. unsigned char *tp = (unsigned char *)addr;
  2171. sprintf(buf, "%u.%u.%u.%u.in-addr.arpa",
  2172. tp[3], tp[2], tp[1], tp[0]);
  2173. }
  2174. #endif
  2175. #ifdef __UCLIBC_HAS_IPV6__
  2176. else {
  2177. char *dst = buf;
  2178. unsigned char *tp = (unsigned char *)addr + addrlen - 1;
  2179. do {
  2180. dst += sprintf(dst, "%x.%x.", tp[i] & 0xf, tp[i] >> 4);
  2181. tp--;
  2182. } while (tp >= (unsigned char *)addr);
  2183. strcpy(dst, "ip6.arpa");
  2184. }
  2185. #endif
  2186. memset(&a, '\0', sizeof(a));
  2187. for (;;) {
  2188. /* Hmm why we memset(a) to zeros only once? */
  2189. packet_len = __dns_lookup(buf, T_PTR, &packet, &a);
  2190. if (packet_len < 0) {
  2191. *h_errnop = HOST_NOT_FOUND;
  2192. return TRY_AGAIN;
  2193. }
  2194. strncpy(buf, a.dotted, buflen);
  2195. free(a.dotted);
  2196. if (a.atype != T_CNAME)
  2197. break;
  2198. DPRINTF("Got a CNAME in gethostbyaddr()\n");
  2199. if (++nest > MAX_RECURSE) {
  2200. *h_errnop = NO_RECOVERY;
  2201. return -1;
  2202. }
  2203. /* Decode CNAME into buf, feed it to __dns_lookup() again */
  2204. i = __decode_dotted(packet, a.rdoffset, packet_len, buf, buflen);
  2205. free(packet);
  2206. if (i < 0) {
  2207. *h_errnop = NO_RECOVERY;
  2208. return -1;
  2209. }
  2210. }
  2211. if (a.atype == T_PTR) { /* ADDRESS */
  2212. i = __decode_dotted(packet, a.rdoffset, packet_len, buf, buflen);
  2213. free(packet);
  2214. result_buf->h_name = buf;
  2215. result_buf->h_addrtype = type;
  2216. result_buf->h_length = addrlen;
  2217. result_buf->h_addr_list = (char **) addr_list;
  2218. result_buf->h_aliases = alias;
  2219. *result = result_buf;
  2220. *h_errnop = NETDB_SUCCESS;
  2221. return NETDB_SUCCESS;
  2222. }
  2223. free(packet);
  2224. *h_errnop = NO_ADDRESS;
  2225. return TRY_AGAIN;
  2226. #undef in6
  2227. }
  2228. libc_hidden_def(gethostbyaddr_r)
  2229. #endif
  2230. #ifdef L_gethostent_r
  2231. __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
  2232. static smallint __stay_open;
  2233. static FILE * __gethostent_fp;
  2234. void endhostent(void)
  2235. {
  2236. __UCLIBC_MUTEX_LOCK(mylock);
  2237. __stay_open = 0;
  2238. if (__gethostent_fp) {
  2239. fclose(__gethostent_fp);
  2240. __gethostent_fp = NULL;
  2241. }
  2242. __UCLIBC_MUTEX_UNLOCK(mylock);
  2243. }
  2244. void sethostent(int stay_open)
  2245. {
  2246. __UCLIBC_MUTEX_LOCK(mylock);
  2247. __stay_open = (stay_open != 0);
  2248. __UCLIBC_MUTEX_UNLOCK(mylock);
  2249. }
  2250. int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen,
  2251. struct hostent **result, int *h_errnop)
  2252. {
  2253. int ret;
  2254. __UCLIBC_MUTEX_LOCK(mylock);
  2255. if (__gethostent_fp == NULL) {
  2256. __gethostent_fp = __open_etc_hosts();
  2257. if (__gethostent_fp == NULL) {
  2258. *result = NULL;
  2259. ret = TRY_AGAIN;
  2260. goto DONE;
  2261. }
  2262. }
  2263. ret = __read_etc_hosts_r(__gethostent_fp, NULL, AF_INET, GETHOSTENT,
  2264. result_buf, buf, buflen, result, h_errnop);
  2265. if (__stay_open == 0) {
  2266. fclose(__gethostent_fp);
  2267. __gethostent_fp = NULL;
  2268. }
  2269. DONE:
  2270. __UCLIBC_MUTEX_UNLOCK(mylock);
  2271. return ret;
  2272. }
  2273. libc_hidden_def(gethostent_r)
  2274. #endif
  2275. #ifdef L_gethostent
  2276. struct hostent *gethostent(void)
  2277. {
  2278. static struct hostent h;
  2279. static char buf[
  2280. #ifndef __UCLIBC_HAS_IPV6__
  2281. sizeof(struct in_addr) + sizeof(struct in_addr *) * 2 +
  2282. #else
  2283. sizeof(struct in6_addr) + sizeof(struct in6_addr *) * 2 +
  2284. #endif /* __UCLIBC_HAS_IPV6__ */
  2285. sizeof(char *) * ALIAS_DIM +
  2286. 80 /*namebuffer*/ + 2 /* margin */];
  2287. struct hostent *host;
  2288. gethostent_r(&h, buf, sizeof(buf), &host, &h_errno);
  2289. return host;
  2290. }
  2291. #endif
  2292. #ifdef L_gethostbyname2
  2293. struct hostent *gethostbyname2(const char *name, int family)
  2294. {
  2295. #ifndef __UCLIBC_HAS_IPV6__
  2296. return family == AF_INET ? gethostbyname(name) : (struct hostent*)NULL;
  2297. #else
  2298. static struct hostent h;
  2299. static char buf[sizeof(struct in6_addr) +
  2300. sizeof(struct in6_addr *) * 2 +
  2301. sizeof(char *)*ALIAS_DIM + 384/*namebuffer*/ + 32/* margin */];
  2302. struct hostent *hp;
  2303. gethostbyname2_r(name, family, &h, buf, sizeof(buf), &hp, &h_errno);
  2304. return hp;
  2305. #endif
  2306. }
  2307. libc_hidden_def(gethostbyname2)
  2308. #endif
  2309. #ifdef L_gethostbyname
  2310. struct hostent *gethostbyname(const char *name)
  2311. {
  2312. #ifndef __UCLIBC_HAS_IPV6__
  2313. static struct hostent h;
  2314. static char buf[sizeof(struct in_addr) +
  2315. sizeof(struct in_addr *) * 2 +
  2316. sizeof(char *)*ALIAS_DIM + 384/*namebuffer*/ + 32/* margin */];
  2317. struct hostent *hp;
  2318. gethostbyname_r(name, &h, buf, sizeof(buf), &hp, &h_errno);
  2319. return hp;
  2320. #else
  2321. return gethostbyname2(name, AF_INET);
  2322. #endif
  2323. }
  2324. libc_hidden_def(gethostbyname)
  2325. #endif
  2326. #ifdef L_gethostbyaddr
  2327. struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type)
  2328. {
  2329. static struct hostent h;
  2330. static char buf[
  2331. #ifndef __UCLIBC_HAS_IPV6__
  2332. sizeof(struct in_addr) + sizeof(struct in_addr *)*2 +
  2333. #else
  2334. sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 +
  2335. #endif /* __UCLIBC_HAS_IPV6__ */
  2336. sizeof(char *)*ALIAS_DIM + 384 /*namebuffer*/ + 32 /* margin */];
  2337. struct hostent *hp;
  2338. gethostbyaddr_r(addr, len, type, &h, buf, sizeof(buf), &hp, &h_errno);
  2339. return hp;
  2340. }
  2341. libc_hidden_def(gethostbyaddr)
  2342. #endif
  2343. #ifdef L_res_comp
  2344. /*
  2345. * Expand compressed domain name 'comp_dn' to full domain name.
  2346. * 'msg' is a pointer to the begining of the message,
  2347. * 'eomorig' points to the first location after the message,
  2348. * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
  2349. * Return size of compressed name or -1 if there was an error.
  2350. */
  2351. int dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
  2352. char *dst, int dstsiz)
  2353. {
  2354. int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
  2355. if (n > 0 && dst[0] == '.')
  2356. dst[0] = '\0';
  2357. return n;
  2358. }
  2359. #endif /* L_res_comp */
  2360. #ifdef L_ns_name
  2361. /* Thinking in noninternationalized USASCII (per the DNS spec),
  2362. * is this character visible and not a space when printed ?
  2363. */
  2364. static int printable(int ch)
  2365. {
  2366. return (ch > 0x20 && ch < 0x7f);
  2367. }
  2368. /* Thinking in noninternationalized USASCII (per the DNS spec),
  2369. * is this characted special ("in need of quoting") ?
  2370. */
  2371. static int special(int ch)
  2372. {
  2373. switch (ch) {
  2374. case 0x22: /* '"' */
  2375. case 0x2E: /* '.' */
  2376. case 0x3B: /* ';' */
  2377. case 0x5C: /* '\\' */
  2378. /* Special modifiers in zone files. */
  2379. case 0x40: /* '@' */
  2380. case 0x24: /* '$' */
  2381. return 1;
  2382. default:
  2383. return 0;
  2384. }
  2385. }
  2386. /*
  2387. * ns_name_uncompress(msg, eom, src, dst, dstsiz)
  2388. * Expand compressed domain name to presentation format.
  2389. * return:
  2390. * Number of bytes read out of `src', or -1 (with errno set).
  2391. * note:
  2392. * Root domain returns as "." not "".
  2393. */
  2394. int ns_name_uncompress(const u_char *msg, const u_char *eom,
  2395. const u_char *src, char *dst, size_t dstsiz)
  2396. {
  2397. u_char tmp[NS_MAXCDNAME];
  2398. int n;
  2399. n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp);
  2400. if (n == -1)
  2401. return -1;
  2402. if (ns_name_ntop(tmp, dst, dstsiz) == -1)
  2403. return -1;
  2404. return n;
  2405. }
  2406. libc_hidden_def(ns_name_uncompress)
  2407. /*
  2408. * ns_name_ntop(src, dst, dstsiz)
  2409. * Convert an encoded domain name to printable ascii as per RFC1035.
  2410. * return:
  2411. * Number of bytes written to buffer, or -1 (with errno set)
  2412. * notes:
  2413. * The root is returned as "."
  2414. * All other domains are returned in non absolute form
  2415. */
  2416. int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
  2417. {
  2418. static const char digits[] = "0123456789";
  2419. const u_char *cp;
  2420. char *dn, *eom;
  2421. u_char c;
  2422. u_int n;
  2423. cp = src;
  2424. dn = dst;
  2425. eom = dst + dstsiz;
  2426. while ((n = *cp++) != 0) {
  2427. if ((n & NS_CMPRSFLGS) != 0) {
  2428. /* Some kind of compression pointer. */
  2429. __set_errno(EMSGSIZE);
  2430. return -1;
  2431. }
  2432. if (dn != dst) {
  2433. if (dn >= eom) {
  2434. __set_errno(EMSGSIZE);
  2435. return -1;
  2436. }
  2437. *dn++ = '.';
  2438. }
  2439. if (dn + n >= eom) {
  2440. __set_errno(EMSGSIZE);
  2441. return -1;
  2442. }
  2443. for (; n > 0; n--) {
  2444. c = *cp++;
  2445. if (special(c)) {
  2446. if (dn + 1 >= eom) {
  2447. __set_errno(EMSGSIZE);
  2448. return -1;
  2449. }
  2450. *dn++ = '\\';
  2451. *dn++ = (char)c;
  2452. } else if (!printable(c)) {
  2453. if (dn + 3 >= eom) {
  2454. __set_errno(EMSGSIZE);
  2455. return -1;
  2456. }
  2457. *dn++ = '\\';
  2458. *dn++ = digits[c / 100];
  2459. *dn++ = digits[(c % 100) / 10];
  2460. *dn++ = digits[c % 10];
  2461. } else {
  2462. if (dn >= eom) {
  2463. __set_errno(EMSGSIZE);
  2464. return -1;
  2465. }
  2466. *dn++ = (char)c;
  2467. }
  2468. }
  2469. }
  2470. if (dn == dst) {
  2471. if (dn >= eom) {
  2472. __set_errno(EMSGSIZE);
  2473. return -1;
  2474. }
  2475. *dn++ = '.';
  2476. }
  2477. if (dn >= eom) {
  2478. __set_errno(EMSGSIZE);
  2479. return -1;
  2480. }
  2481. *dn++ = '\0';
  2482. return (dn - dst);
  2483. }
  2484. libc_hidden_def(ns_name_ntop)
  2485. /*
  2486. * ns_name_unpack(msg, eom, src, dst, dstsiz)
  2487. * Unpack a domain name from a message, source may be compressed.
  2488. * return:
  2489. * -1 if it fails, or consumed octets if it succeeds.
  2490. */
  2491. int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
  2492. u_char *dst, size_t dstsiz)
  2493. {
  2494. const u_char *srcp, *dstlim;
  2495. u_char *dstp;
  2496. int n, len, checked;
  2497. len = -1;
  2498. checked = 0;
  2499. dstp = dst;
  2500. srcp = src;
  2501. dstlim = dst + dstsiz;
  2502. if (srcp < msg || srcp >= eom) {
  2503. __set_errno(EMSGSIZE);
  2504. return -1;
  2505. }
  2506. /* Fetch next label in domain name. */
  2507. while ((n = *srcp++) != 0) {
  2508. /* Check for indirection. */
  2509. switch (n & NS_CMPRSFLGS) {
  2510. case 0:
  2511. /* Limit checks. */
  2512. if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
  2513. __set_errno(EMSGSIZE);
  2514. return -1;
  2515. }
  2516. checked += n + 1;
  2517. *dstp++ = n;
  2518. memcpy(dstp, srcp, n);
  2519. dstp += n;
  2520. srcp += n;
  2521. break;
  2522. case NS_CMPRSFLGS:
  2523. if (srcp >= eom) {
  2524. __set_errno(EMSGSIZE);
  2525. return -1;
  2526. }
  2527. if (len < 0)
  2528. len = srcp - src + 1;
  2529. srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
  2530. if (srcp < msg || srcp >= eom) { /* Out of range. */
  2531. __set_errno(EMSGSIZE);
  2532. return -1;
  2533. }
  2534. checked += 2;
  2535. /*
  2536. * Check for loops in the compressed name;
  2537. * if we've looked at the whole message,
  2538. * there must be a loop.
  2539. */
  2540. if (checked >= eom - msg) {
  2541. __set_errno(EMSGSIZE);
  2542. return -1;
  2543. }
  2544. break;
  2545. default:
  2546. __set_errno(EMSGSIZE);
  2547. return -1; /* flag error */
  2548. }
  2549. }
  2550. *dstp = '\0';
  2551. if (len < 0)
  2552. len = srcp - src;
  2553. return len;
  2554. }
  2555. libc_hidden_def(ns_name_unpack)
  2556. #endif /* L_ns_name */
  2557. #ifdef L_res_init
  2558. /* Protected by __resolv_lock */
  2559. struct __res_state _res;
  2560. /* Will be called under __resolv_lock. */
  2561. static void res_sync_func(void)
  2562. {
  2563. struct __res_state *rp = &(_res);
  2564. int n;
  2565. /* If we didn't get malloc failure earlier... */
  2566. if (__nameserver != (void*) &__local_nameserver) {
  2567. /* TODO:
  2568. * if (__nameservers < rp->nscount) - try to grow __nameserver[]?
  2569. */
  2570. #ifdef __UCLIBC_HAS_IPV6__
  2571. if (__nameservers > rp->_u._ext.nscount)
  2572. __nameservers = rp->_u._ext.nscount;
  2573. n = __nameservers;
  2574. while (--n >= 0)
  2575. __nameserver[n].sa6 = *rp->_u._ext.nsaddrs[n]; /* struct copy */
  2576. #else /* IPv4 only */
  2577. if (__nameservers > rp->nscount)
  2578. __nameservers = rp->nscount;
  2579. n = __nameservers;
  2580. while (--n >= 0)
  2581. __nameserver[n].sa4 = rp->nsaddr_list[n]; /* struct copy */
  2582. #endif
  2583. }
  2584. /* Extend and comment what program is known
  2585. * to use which _res.XXX member(s).
  2586. __resolv_opts = rp->options;
  2587. ...
  2588. */
  2589. }
  2590. /* Our res_init never fails (always returns 0) */
  2591. int res_init(void)
  2592. {
  2593. struct __res_state *rp = &(_res);
  2594. int i;
  2595. int n;
  2596. #ifdef __UCLIBC_HAS_IPV6__
  2597. int m = 0;
  2598. #endif
  2599. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  2600. __close_nameservers();
  2601. __open_nameservers();
  2602. __res_sync = res_sync_func;
  2603. memset(rp, 0, sizeof(*rp));
  2604. rp->options = RES_INIT;
  2605. #ifdef __UCLIBC_HAS_COMPAT_RES_STATE__
  2606. rp->retrans = RES_TIMEOUT;
  2607. rp->retry = 4;
  2608. /*TODO: pulls in largish static buffers... use simpler one? */
  2609. rp->id = random();
  2610. #endif
  2611. rp->ndots = 1;
  2612. #ifdef __UCLIBC_HAS_EXTRA_COMPAT_RES_STATE__
  2613. rp->_vcsock = -1;
  2614. #endif
  2615. n = __searchdomains;
  2616. if (n > ARRAY_SIZE(rp->dnsrch))
  2617. n = ARRAY_SIZE(rp->dnsrch);
  2618. for (i = 0; i < n; i++)
  2619. rp->dnsrch[i] = __searchdomain[i];
  2620. /* copy nameservers' addresses */
  2621. i = 0;
  2622. #ifdef __UCLIBC_HAS_IPV4__
  2623. n = 0;
  2624. while (n < ARRAY_SIZE(rp->nsaddr_list) && i < __nameservers) {
  2625. if (__nameserver[i].sa.sa_family == AF_INET) {
  2626. rp->nsaddr_list[n] = __nameserver[i].sa4; /* struct copy */
  2627. #ifdef __UCLIBC_HAS_IPV6__
  2628. if (m < ARRAY_SIZE(rp->_u._ext.nsaddrs)) {
  2629. rp->_u._ext.nsaddrs[m] = (void*) &rp->nsaddr_list[n];
  2630. m++;
  2631. }
  2632. #endif
  2633. n++;
  2634. }
  2635. #ifdef __UCLIBC_HAS_IPV6__
  2636. if (__nameserver[i].sa.sa_family == AF_INET6
  2637. && m < ARRAY_SIZE(rp->_u._ext.nsaddrs)
  2638. ) {
  2639. struct sockaddr_in6 *sa6 = malloc(sizeof(sa6));
  2640. if (sa6) {
  2641. *sa6 = __nameserver[i].sa6; /* struct copy */
  2642. rp->_u._ext.nsaddrs[m] = sa6;
  2643. m++;
  2644. }
  2645. }
  2646. #endif
  2647. i++;
  2648. }
  2649. rp->nscount = n;
  2650. #ifdef __UCLIBC_HAS_IPV6__
  2651. rp->_u._ext.nscount = m;
  2652. #endif
  2653. #else /* IPv6 only */
  2654. while (m < ARRAY_SIZE(rp->_u._ext.nsaddrs) && i < __nameservers) {
  2655. struct sockaddr_in6 *sa6 = malloc(sizeof(sa6));
  2656. if (sa6) {
  2657. *sa6 = __nameserver[i].sa6; /* struct copy */
  2658. rp->_u._ext.nsaddrs[m] = sa6;
  2659. m++;
  2660. }
  2661. i++;
  2662. }
  2663. rp->_u._ext.nscount = m;
  2664. #endif
  2665. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  2666. return 0;
  2667. }
  2668. libc_hidden_def(res_init)
  2669. #ifdef __UCLIBC_HAS_BSD_RES_CLOSE__
  2670. void res_close(void)
  2671. {
  2672. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  2673. __close_nameservers();
  2674. __res_sync = NULL;
  2675. #ifdef __UCLIBC_HAS_IPV6__
  2676. {
  2677. char *p1 = (char*) &(_res.nsaddr_list[0]);
  2678. int m = 0;
  2679. /* free nsaddrs[m] if they do not point to nsaddr_list[x] */
  2680. while (m < ARRAY_SIZE(_res._u._ext.nsaddrs)) {
  2681. char *p2 = (char*)(_res._u._ext.nsaddrs[m]);
  2682. if (p2 < p1 || (p2 - p1) > sizeof(_res.nsaddr_list))
  2683. free(p2);
  2684. }
  2685. }
  2686. #endif
  2687. memset(&_res, 0, sizeof(_res));
  2688. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  2689. }
  2690. #endif
  2691. #endif /* L_res_init */
  2692. #ifdef L_res_query
  2693. int res_query(const char *dname, int class, int type,
  2694. unsigned char *answer, int anslen)
  2695. {
  2696. int i;
  2697. unsigned char *packet = NULL;
  2698. struct resolv_answer a;
  2699. if (!dname || class != 1 /* CLASS_IN */) {
  2700. h_errno = NO_RECOVERY;
  2701. return -1;
  2702. }
  2703. memset(&a, '\0', sizeof(a));
  2704. i = __dns_lookup(dname, type, &packet, &a);
  2705. if (i < 0) {
  2706. if (!h_errno) /* TODO: can this ever happen? */
  2707. h_errno = TRY_AGAIN;
  2708. return -1;
  2709. }
  2710. free(a.dotted);
  2711. if (a.atype == type) { /* CNAME */
  2712. if (i > anslen)
  2713. i = anslen;
  2714. memcpy(answer, packet, i);
  2715. }
  2716. free(packet);
  2717. return i;
  2718. }
  2719. libc_hidden_def(res_query)
  2720. /*
  2721. * Formulate a normal query, send, and retrieve answer in supplied buffer.
  2722. * Return the size of the response on success, -1 on error.
  2723. * If enabled, implement search rules until answer or unrecoverable failure
  2724. * is detected. Error code, if any, is left in h_errno.
  2725. */
  2726. #define __TRAILING_DOT (1<<0)
  2727. #define __GOT_NODATA (1<<1)
  2728. #define __GOT_SERVFAIL (1<<2)
  2729. #define __TRIED_AS_IS (1<<3)
  2730. int res_search(const char *name, int class, int type, u_char *answer,
  2731. int anslen)
  2732. {
  2733. const char *cp;
  2734. char **domain;
  2735. HEADER *hp = (HEADER *)(void *)answer;
  2736. unsigned dots;
  2737. unsigned state;
  2738. int ret, saved_herrno;
  2739. uint32_t _res_options;
  2740. unsigned _res_ndots;
  2741. char **_res_dnsrch;
  2742. if (!name || !answer) {
  2743. h_errno = NETDB_INTERNAL;
  2744. return -1;
  2745. }
  2746. again:
  2747. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  2748. _res_options = _res.options;
  2749. _res_ndots = _res.ndots;
  2750. _res_dnsrch = _res.dnsrch;
  2751. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  2752. if (!(_res_options & RES_INIT)) {
  2753. res_init(); /* our res_init never fails */
  2754. goto again;
  2755. }
  2756. state = 0;
  2757. errno = 0;
  2758. h_errno = HOST_NOT_FOUND; /* default, if we never query */
  2759. dots = 0;
  2760. for (cp = name; *cp; cp++)
  2761. dots += (*cp == '.');
  2762. if (cp > name && *--cp == '.')
  2763. state |= __TRAILING_DOT;
  2764. /*
  2765. * If there are dots in the name already, let's just give it a try
  2766. * 'as is'. The threshold can be set with the "ndots" option.
  2767. */
  2768. saved_herrno = -1;
  2769. if (dots >= _res_ndots) {
  2770. ret = res_querydomain(name, NULL, class, type, answer, anslen);
  2771. if (ret > 0)
  2772. return ret;
  2773. saved_herrno = h_errno;
  2774. state |= __TRIED_AS_IS;
  2775. }
  2776. /*
  2777. * We do at least one level of search if
  2778. * - there is no dot and RES_DEFNAME is set, or
  2779. * - there is at least one dot, there is no trailing dot,
  2780. * and RES_DNSRCH is set.
  2781. */
  2782. if ((!dots && (_res_options & RES_DEFNAMES))
  2783. || (dots && !(state & __TRAILING_DOT) && (_res_options & RES_DNSRCH))
  2784. ) {
  2785. bool done = 0;
  2786. for (domain = _res_dnsrch; *domain && !done; domain++) {
  2787. ret = res_querydomain(name, *domain, class, type,
  2788. answer, anslen);
  2789. if (ret > 0)
  2790. return ret;
  2791. /*
  2792. * If no server present, give up.
  2793. * If name isn't found in this domain,
  2794. * keep trying higher domains in the search list
  2795. * (if that's enabled).
  2796. * On a NO_DATA error, keep trying, otherwise
  2797. * a wildcard entry of another type could keep us
  2798. * from finding this entry higher in the domain.
  2799. * If we get some other error (negative answer or
  2800. * server failure), then stop searching up,
  2801. * but try the input name below in case it's
  2802. * fully-qualified.
  2803. */
  2804. if (errno == ECONNREFUSED) {
  2805. h_errno = TRY_AGAIN;
  2806. return -1;
  2807. }
  2808. switch (h_errno) {
  2809. case NO_DATA:
  2810. state |= __GOT_NODATA;
  2811. /* FALLTHROUGH */
  2812. case HOST_NOT_FOUND:
  2813. /* keep trying */
  2814. break;
  2815. case TRY_AGAIN:
  2816. if (hp->rcode == SERVFAIL) {
  2817. /* try next search element, if any */
  2818. state |= __GOT_SERVFAIL;
  2819. break;
  2820. }
  2821. /* FALLTHROUGH */
  2822. default:
  2823. /* anything else implies that we're done */
  2824. done = 1;
  2825. }
  2826. /*
  2827. * if we got here for some reason other than DNSRCH,
  2828. * we only wanted one iteration of the loop, so stop.
  2829. */
  2830. if (!(_res_options & RES_DNSRCH))
  2831. done = 1;
  2832. }
  2833. }
  2834. /*
  2835. * if we have not already tried the name "as is", do that now.
  2836. * note that we do this regardless of how many dots were in the
  2837. * name or whether it ends with a dot.
  2838. */
  2839. if (!(state & __TRIED_AS_IS)) {
  2840. ret = res_querydomain(name, NULL, class, type, answer, anslen);
  2841. if (ret > 0)
  2842. return ret;
  2843. }
  2844. /*
  2845. * if we got here, we didn't satisfy the search.
  2846. * if we did an initial full query, return that query's h_errno
  2847. * (note that we wouldn't be here if that query had succeeded).
  2848. * else if we ever got a nodata, send that back as the reason.
  2849. * else send back meaningless h_errno, that being the one from
  2850. * the last DNSRCH we did.
  2851. */
  2852. if (saved_herrno != -1)
  2853. h_errno = saved_herrno;
  2854. else if (state & __GOT_NODATA)
  2855. h_errno = NO_DATA;
  2856. else if (state & __GOT_SERVFAIL)
  2857. h_errno = TRY_AGAIN;
  2858. return -1;
  2859. }
  2860. #undef __TRAILING_DOT
  2861. #undef __GOT_NODATA
  2862. #undef __GOT_SERVFAIL
  2863. #undef __TRIED_AS_IS
  2864. /*
  2865. * Perform a call on res_query on the concatenation of name and domain,
  2866. * removing a trailing dot from name if domain is NULL.
  2867. */
  2868. int res_querydomain(const char *name, const char *domain, int class, int type,
  2869. u_char *answer, int anslen)
  2870. {
  2871. char nbuf[MAXDNAME];
  2872. const char *longname = nbuf;
  2873. size_t n, d;
  2874. #ifdef DEBUG
  2875. uint32_t _res_options;
  2876. #endif
  2877. if (!name || !answer) {
  2878. h_errno = NETDB_INTERNAL;
  2879. return -1;
  2880. }
  2881. #ifdef DEBUG
  2882. again:
  2883. __UCLIBC_MUTEX_LOCK(__resolv_lock);
  2884. _res_options = _res.options;
  2885. __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
  2886. if (!(_res_options & RES_INIT)) {
  2887. res_init(); /* our res_init never fails */
  2888. goto again;
  2889. }
  2890. if (_res_options & RES_DEBUG)
  2891. printf(";; res_querydomain(%s, %s, %d, %d)\n",
  2892. name, (domain ? domain : "<Nil>"), class, type);
  2893. #endif
  2894. if (domain == NULL) {
  2895. /*
  2896. * Check for trailing '.';
  2897. * copy without '.' if present.
  2898. */
  2899. n = strlen(name);
  2900. if (n + 1 > sizeof(nbuf)) {
  2901. h_errno = NO_RECOVERY;
  2902. return -1;
  2903. }
  2904. if (n > 0 && name[--n] == '.') {
  2905. strncpy(nbuf, name, n);
  2906. nbuf[n] = '\0';
  2907. } else
  2908. longname = name;
  2909. } else {
  2910. n = strlen(name);
  2911. d = strlen(domain);
  2912. if (n + 1 + d + 1 > sizeof(nbuf)) {
  2913. h_errno = NO_RECOVERY;
  2914. return -1;
  2915. }
  2916. snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
  2917. }
  2918. return res_query(longname, class, type, answer, anslen);
  2919. }
  2920. libc_hidden_def(res_querydomain)
  2921. #endif
  2922. /* Unimplemented: */
  2923. /* res_mkquery */
  2924. /* res_send */
  2925. /* dn_comp */