resolv.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629
  1. /* resolv.c: DNS Resolver
  2. *
  3. * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
  4. * The Silver Hammer Group, Ltd.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Library General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * 5-Oct-2000 W. Greathouse wgreathouse@smva.com
  12. * Fix memory leak and memory corruption.
  13. * -- Every name resolution resulted in
  14. * a new parse of resolv.conf and new
  15. * copy of nameservers allocated by
  16. * strdup.
  17. * -- Every name resolution resulted in
  18. * a new read of resolv.conf without
  19. * resetting index from prior read...
  20. * resulting in exceeding array bounds.
  21. *
  22. * Limit nameservers read from resolv.conf
  23. *
  24. * Add "search" domains from resolv.conf
  25. *
  26. * Some systems will return a security
  27. * signature along with query answer for
  28. * dynamic DNS entries.
  29. * -- skip/ignore this answer
  30. *
  31. * Include arpa/nameser.h for defines.
  32. *
  33. * General cleanup
  34. *
  35. * 20-Jun-2001 Michal Moskal <malekith@pld.org.pl>
  36. * partial IPv6 support (i.e. gethostbyname2() and resolve_address2()
  37. * functions added), IPv6 nameservers are also supported.
  38. *
  39. * 6-Oct-2001 Jari Korva <jari.korva@iki.fi>
  40. * more IPv6 support (IPv6 support for gethostbyaddr();
  41. * address family parameter and improved IPv6 support for get_hosts_byname
  42. * and read_etc_hosts; getnameinfo() port from glibc; defined
  43. * defined ip6addr_any and in6addr_loopback)
  44. */
  45. #define __FORCE_GLIBC
  46. #include <features.h>
  47. #include <string.h>
  48. #include <stdio.h>
  49. #include <signal.h>
  50. #include <errno.h>
  51. #include <sys/socket.h>
  52. #include <sys/types.h>
  53. #include <netinet/in.h>
  54. #include <arpa/inet.h>
  55. #include <stdlib.h>
  56. #include <unistd.h>
  57. #include <resolv.h>
  58. #include <netdb.h>
  59. #include <ctype.h>
  60. #include <arpa/nameser.h>
  61. #include <sys/utsname.h>
  62. #include <sys/un.h>
  63. #define MAX_RECURSE 5
  64. #define REPLY_TIMEOUT 10
  65. #define MAX_RETRIES 15
  66. #define MAX_SERVERS 3
  67. #define MAX_SEARCH 4
  68. #undef DEBUG
  69. /*#define DEBUG*/
  70. #ifdef DEBUG
  71. #define DPRINTF(X,args...) fprintf(stderr, X, ##args)
  72. #else
  73. #define DPRINTF(X,args...)
  74. #endif /* DEBUG */
  75. struct resolv_header {
  76. int id;
  77. int qr,opcode,aa,tc,rd,ra,rcode;
  78. int qdcount;
  79. int ancount;
  80. int nscount;
  81. int arcount;
  82. };
  83. struct resolv_question {
  84. char * dotted;
  85. int qtype;
  86. int qclass;
  87. };
  88. struct resolv_answer {
  89. char * dotted;
  90. int atype;
  91. int aclass;
  92. int ttl;
  93. int rdlength;
  94. unsigned char * rdata;
  95. int rdoffset;
  96. };
  97. extern int nameservers;
  98. extern char * nameserver[MAX_SERVERS];
  99. extern int searchdomains;
  100. extern char * searchdomain[MAX_SEARCH];
  101. extern struct hostent * get_hosts_byname(const char * name, int type);
  102. extern struct hostent * get_hosts_byaddr(const char * addr, int len, int type);
  103. extern struct hostent * read_etc_hosts(const char * name, int type, int ip);
  104. extern int resolve_address(const char * address, int nscount,
  105. char ** nsip, struct in_addr * in);
  106. extern int resolve_mailbox(const char * address, int nscount,
  107. char ** nsip, struct in_addr * in);
  108. extern int dns_lookup(const char * name, int type, int nscount,
  109. char ** nsip, unsigned char ** outpacket, struct resolv_answer * a);
  110. int encode_dotted(const char * dotted, unsigned char * dest, int maxlen);
  111. int decode_dotted(const unsigned char * message, int offset,
  112. char * dest, int maxlen);
  113. int length_dotted(const unsigned char * message, int offset);
  114. int encode_header(struct resolv_header * h, unsigned char * dest, int maxlen);
  115. int decode_header(unsigned char * data, struct resolv_header * h);
  116. int encode_question(struct resolv_question * q,
  117. unsigned char * dest, int maxlen);
  118. int decode_question(unsigned char * message, int offset,
  119. struct resolv_question * q);
  120. int encode_answer(struct resolv_answer * a,
  121. unsigned char * dest, int maxlen);
  122. int decode_answer(unsigned char * message, int offset,
  123. struct resolv_answer * a);
  124. int length_question(unsigned char * message, int offset);
  125. extern int open_nameservers(void);
  126. #ifdef L_encodeh
  127. int encode_header(struct resolv_header *h, unsigned char *dest, int maxlen)
  128. {
  129. if (maxlen < HFIXEDSZ)
  130. return -1;
  131. dest[0] = (h->id & 0xff00) >> 8;
  132. dest[1] = (h->id & 0x00ff) >> 0;
  133. dest[2] = (h->qr ? 0x80 : 0) |
  134. ((h->opcode & 0x0f) << 3) |
  135. (h->aa ? 0x04 : 0) |
  136. (h->tc ? 0x02 : 0) |
  137. (h->rd ? 0x01 : 0);
  138. dest[3] = (h->ra ? 0x80 : 0) | (h->rcode & 0x0f);
  139. dest[4] = (h->qdcount & 0xff00) >> 8;
  140. dest[5] = (h->qdcount & 0x00ff) >> 0;
  141. dest[6] = (h->ancount & 0xff00) >> 8;
  142. dest[7] = (h->ancount & 0x00ff) >> 0;
  143. dest[8] = (h->nscount & 0xff00) >> 8;
  144. dest[9] = (h->nscount & 0x00ff) >> 0;
  145. dest[10] = (h->arcount & 0xff00) >> 8;
  146. dest[11] = (h->arcount & 0x00ff) >> 0;
  147. return HFIXEDSZ;
  148. }
  149. #endif
  150. #ifdef L_decodeh
  151. int decode_header(unsigned char *data, struct resolv_header *h)
  152. {
  153. h->id = (data[0] << 8) | data[1];
  154. h->qr = (data[2] & 0x80) ? 1 : 0;
  155. h->opcode = (data[2] >> 3) & 0x0f;
  156. h->aa = (data[2] & 0x04) ? 1 : 0;
  157. h->tc = (data[2] & 0x02) ? 1 : 0;
  158. h->rd = (data[2] & 0x01) ? 1 : 0;
  159. h->ra = (data[3] & 0x80) ? 1 : 0;
  160. h->rcode = data[3] & 0x0f;
  161. h->qdcount = (data[4] << 8) | data[5];
  162. h->ancount = (data[6] << 8) | data[7];
  163. h->nscount = (data[8] << 8) | data[9];
  164. h->arcount = (data[10] << 8) | data[11];
  165. return HFIXEDSZ;
  166. }
  167. #endif
  168. #ifdef L_encoded
  169. /* Encode a dotted string into nameserver transport-level encoding.
  170. This routine is fairly dumb, and doesn't attempt to compress
  171. the data */
  172. int encode_dotted(const char *dotted, unsigned char *dest, int maxlen)
  173. {
  174. int used = 0;
  175. while (dotted && *dotted) {
  176. char *c = strchr(dotted, '.');
  177. int l = c ? c - dotted : strlen(dotted);
  178. if (l >= (maxlen - used - 1))
  179. return -1;
  180. dest[used++] = l;
  181. memcpy(dest + used, dotted, l);
  182. used += l;
  183. if (c)
  184. dotted = c + 1;
  185. else
  186. break;
  187. }
  188. if (maxlen < 1)
  189. return -1;
  190. dest[used++] = 0;
  191. return used;
  192. }
  193. #endif
  194. #ifdef L_decoded
  195. /* Decode a dotted string from nameserver transport-level encoding.
  196. This routine understands compressed data. */
  197. int decode_dotted(const unsigned char *data, int offset,
  198. char *dest, int maxlen)
  199. {
  200. int l;
  201. int measure = 1;
  202. int total = 0;
  203. int used = 0;
  204. if (!data)
  205. return -1;
  206. while ((l=data[offset++])) {
  207. if (measure)
  208. total++;
  209. if ((l & 0xc0) == (0xc0)) {
  210. if (measure)
  211. total++;
  212. /* compressed item, redirect */
  213. offset = ((l & 0x3f) << 8) | data[offset];
  214. measure = 0;
  215. continue;
  216. }
  217. if ((used + l + 1) >= maxlen)
  218. return -1;
  219. memcpy(dest + used, data + offset, l);
  220. offset += l;
  221. used += l;
  222. if (measure)
  223. total += l;
  224. if (data[offset] != 0)
  225. dest[used++] = '.';
  226. else
  227. dest[used++] = '\0';
  228. }
  229. DPRINTF("Total decode len = %d\n", total);
  230. return total;
  231. }
  232. #endif
  233. #ifdef L_lengthd
  234. int length_dotted(const unsigned char *data, int offset)
  235. {
  236. int orig_offset = offset;
  237. int l;
  238. if (!data)
  239. return -1;
  240. while ((l = data[offset++])) {
  241. if ((l & 0xc0) == (0xc0)) {
  242. offset++;
  243. break;
  244. }
  245. offset += l;
  246. }
  247. return offset - orig_offset;
  248. }
  249. #endif
  250. #ifdef L_encodeq
  251. int encode_question(struct resolv_question *q,
  252. unsigned char *dest, int maxlen)
  253. {
  254. int i;
  255. i = encode_dotted(q->dotted, dest, maxlen);
  256. if (i < 0)
  257. return i;
  258. dest += i;
  259. maxlen -= i;
  260. if (maxlen < 4)
  261. return -1;
  262. dest[0] = (q->qtype & 0xff00) >> 8;
  263. dest[1] = (q->qtype & 0x00ff) >> 0;
  264. dest[2] = (q->qclass & 0xff00) >> 8;
  265. dest[3] = (q->qclass & 0x00ff) >> 0;
  266. return i + 4;
  267. }
  268. #endif
  269. #ifdef L_decodeq
  270. int decode_question(unsigned char *message, int offset,
  271. struct resolv_question *q)
  272. {
  273. char temp[256];
  274. int i;
  275. i = decode_dotted(message, offset, temp, sizeof(temp));
  276. if (i < 0)
  277. return i;
  278. offset += i;
  279. q->dotted = strdup(temp);
  280. q->qtype = (message[offset + 0] << 8) | message[offset + 1];
  281. q->qclass = (message[offset + 2] << 8) | message[offset + 3];
  282. return i + 4;
  283. }
  284. #endif
  285. #ifdef L_lengthq
  286. int length_question(unsigned char *message, int offset)
  287. {
  288. int i;
  289. i = length_dotted(message, offset);
  290. if (i < 0)
  291. return i;
  292. return i + 4;
  293. }
  294. #endif
  295. #ifdef L_encodea
  296. int encode_answer(struct resolv_answer *a, unsigned char *dest, int maxlen)
  297. {
  298. int i;
  299. i = encode_dotted(a->dotted, dest, maxlen);
  300. if (i < 0)
  301. return i;
  302. dest += i;
  303. maxlen -= i;
  304. if (maxlen < (RRFIXEDSZ+a->rdlength))
  305. return -1;
  306. *dest++ = (a->atype & 0xff00) >> 8;
  307. *dest++ = (a->atype & 0x00ff) >> 0;
  308. *dest++ = (a->aclass & 0xff00) >> 8;
  309. *dest++ = (a->aclass & 0x00ff) >> 0;
  310. *dest++ = (a->ttl & 0xff000000) >> 24;
  311. *dest++ = (a->ttl & 0x00ff0000) >> 16;
  312. *dest++ = (a->ttl & 0x0000ff00) >> 8;
  313. *dest++ = (a->ttl & 0x000000ff) >> 0;
  314. *dest++ = (a->rdlength & 0xff00) >> 8;
  315. *dest++ = (a->rdlength & 0x00ff) >> 0;
  316. memcpy(dest, a->rdata, a->rdlength);
  317. return i + RRFIXEDSZ + a->rdlength;
  318. }
  319. #endif
  320. #ifdef L_decodea
  321. int decode_answer(unsigned char *message, int offset,
  322. struct resolv_answer *a)
  323. {
  324. char temp[256];
  325. int i;
  326. i = decode_dotted(message, offset, temp, sizeof(temp));
  327. if (i < 0)
  328. return i;
  329. message += offset + i;
  330. a->dotted = strdup(temp);
  331. a->atype = (message[0] << 8) | message[1];
  332. message += 2;
  333. a->aclass = (message[0] << 8) | message[1];
  334. message += 2;
  335. a->ttl = (message[0] << 24) |
  336. (message[1] << 16) | (message[2] << 8) | (message[3] << 0);
  337. message += 4;
  338. a->rdlength = (message[0] << 8) | message[1];
  339. message += 2;
  340. a->rdata = message;
  341. a->rdoffset = offset + i + RRFIXEDSZ;
  342. DPRINTF("i=%d,rdlength=%d\n", i, a->rdlength);
  343. return i + RRFIXEDSZ + a->rdlength;
  344. }
  345. #endif
  346. #ifdef L_encodep
  347. int encode_packet(struct resolv_header *h,
  348. struct resolv_question **q,
  349. struct resolv_answer **an,
  350. struct resolv_answer **ns,
  351. struct resolv_answer **ar,
  352. unsigned char *dest, int maxlen)
  353. {
  354. int i, total = 0;
  355. int j;
  356. i = encode_header(h, dest, maxlen);
  357. if (i < 0)
  358. return i;
  359. dest += i;
  360. maxlen -= i;
  361. total += i;
  362. for (j = 0; j < h->qdcount; j++) {
  363. i = encode_question(q[j], dest, maxlen);
  364. if (i < 0)
  365. return i;
  366. dest += i;
  367. maxlen -= i;
  368. total += i;
  369. }
  370. for (j = 0; j < h->ancount; j++) {
  371. i = encode_answer(an[j], dest, maxlen);
  372. if (i < 0)
  373. return i;
  374. dest += i;
  375. maxlen -= i;
  376. total += i;
  377. }
  378. for (j = 0; j < h->nscount; j++) {
  379. i = encode_answer(ns[j], dest, maxlen);
  380. if (i < 0)
  381. return i;
  382. dest += i;
  383. maxlen -= i;
  384. total += i;
  385. }
  386. for (j = 0; j < h->arcount; j++) {
  387. i = encode_answer(ar[j], dest, maxlen);
  388. if (i < 0)
  389. return i;
  390. dest += i;
  391. maxlen -= i;
  392. total += i;
  393. }
  394. return total;
  395. }
  396. #endif
  397. #ifdef L_decodep
  398. int decode_packet(unsigned char *data, struct resolv_header *h)
  399. {
  400. return decode_header(data, h);
  401. }
  402. #endif
  403. #ifdef L_formquery
  404. int form_query(int id, const char *name, int type, unsigned char *packet,
  405. int maxlen)
  406. {
  407. struct resolv_header h;
  408. struct resolv_question q;
  409. int i, j;
  410. memset(&h, 0, sizeof(h));
  411. h.id = id;
  412. h.qdcount = 1;
  413. q.dotted = (char *) name;
  414. q.qtype = type;
  415. q.qclass = C_IN; /* CLASS_IN */
  416. i = encode_header(&h, packet, maxlen);
  417. if (i < 0)
  418. return i;
  419. j = encode_question(&q, packet + i, maxlen - i);
  420. if (j < 0)
  421. return j;
  422. return i + j;
  423. }
  424. #endif
  425. #ifdef L_dnslookup
  426. int dns_caught_signal = 0;
  427. void dns_catch_signal(int signo)
  428. {
  429. dns_caught_signal = 1;
  430. }
  431. int dns_lookup(const char *name, int type, int nscount, char **nsip,
  432. unsigned char **outpacket, struct resolv_answer *a)
  433. {
  434. static int id = 1;
  435. int i, j, len, fd, pos;
  436. static int ns = 0;
  437. struct sockaddr_in sa;
  438. #ifdef __UCLIBC_HAS_IPV6__
  439. struct sockaddr_in6 sa6;
  440. #endif /* __UCLIBC_HAS_IPV6__ */
  441. int oldalarm;
  442. __sighandler_t oldhandler;
  443. struct resolv_header h;
  444. struct resolv_question q;
  445. int retries = 0;
  446. unsigned char * packet = malloc(PACKETSZ);
  447. unsigned char * lookup = malloc(MAXDNAME);
  448. int variant = 0;
  449. #ifdef __UCLIBC_HAS_IPV6__
  450. int v6;
  451. #endif /* __UCLIBC_HAS_IPV6__ */
  452. fd = -1;
  453. if (!packet || !lookup || !nscount)
  454. goto fail;
  455. DPRINTF("Looking up type %d answer for '%s'\n", type, name);
  456. ns %= nscount;
  457. while (retries++ < MAX_RETRIES) {
  458. #ifdef __UCLIBC_HAS_IPV6__
  459. v6 = (inet_pton(AF_INET6, nsip[ns], &sa6.sin6_addr) > 0);
  460. #endif /* __UCLIBC_HAS_IPV6__ */
  461. if (fd != -1)
  462. close(fd);
  463. #ifndef __UCLIBC_HAS_IPV6__
  464. fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  465. #else /* __UCLIBC_HAS_IPV6__ */
  466. fd = socket(v6 ? AF_INET6 : AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  467. #endif /* __UCLIBC_HAS_IPV6__ */
  468. if (fd == -1)
  469. goto fail;
  470. memset(packet, 0, PACKETSZ);
  471. memset(&h, 0, sizeof(h));
  472. h.id = ++id;
  473. h.qdcount = 1;
  474. h.rd = 1;
  475. DPRINTF("encoding header\n", h.rd);
  476. i = encode_header(&h, packet, PACKETSZ);
  477. if (i < 0)
  478. goto fail;
  479. strncpy(lookup,name,MAXDNAME);
  480. if (variant < searchdomains && strchr(lookup, '.') == NULL)
  481. {
  482. strncat(lookup,".", MAXDNAME);
  483. strncat(lookup,searchdomain[variant], MAXDNAME);
  484. }
  485. DPRINTF("lookup name: %s\n", lookup);
  486. q.dotted = (char *)lookup;
  487. q.qtype = type;
  488. q.qclass = C_IN; /* CLASS_IN */
  489. j = encode_question(&q, packet+i, PACKETSZ-i);
  490. if (j < 0)
  491. goto fail;
  492. len = i + j;
  493. DPRINTF("On try %d, sending query to port %d of machine %s\n",
  494. retries, NAMESERVER_PORT, nsip[ns]);
  495. #ifndef __UCLIBC_HAS_IPV6__
  496. sa.sin_family = AF_INET;
  497. sa.sin_port = htons(NAMESERVER_PORT);
  498. sa.sin_addr.s_addr = inet_addr(nsip[ns]);
  499. #else /* __UCLIBC_HAS_IPV6__ */
  500. if (v6) {
  501. sa6.sin6_family = AF_INET6;
  502. sa6.sin6_port = htons(NAMESERVER_PORT);
  503. /* sa6.sin6_addr is already here */
  504. } else {
  505. sa.sin_family = AF_INET;
  506. sa.sin_port = htons(NAMESERVER_PORT);
  507. sa.sin_addr.s_addr = inet_addr(nsip[ns]);
  508. }
  509. #endif /* __UCLIBC_HAS_IPV6__ */
  510. #ifndef __UCLIBC_HAS_IPV6__
  511. if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
  512. #else /* __UCLIBC_HAS_IPV6__ */
  513. if (connect(fd, (struct sockaddr *) (v6 ? &sa6 : &sa),
  514. v6 ? sizeof(sa6) : sizeof(sa)) == -1) {
  515. #endif /* __UCLIBC_HAS_IPV6__ */
  516. if (errno == ENETUNREACH) {
  517. /* routing error, presume not transient */
  518. goto tryall;
  519. } else
  520. /* retry */
  521. continue;
  522. }
  523. DPRINTF("Transmitting packet of length %d, id=%d, qr=%d\n",
  524. len, h.id, h.qr);
  525. send(fd, packet, len, 0);
  526. dns_caught_signal = 0;
  527. oldalarm = alarm(REPLY_TIMEOUT);
  528. oldhandler = signal(SIGALRM, dns_catch_signal);
  529. i = recv(fd, packet, PACKETSZ, 0);
  530. alarm(0);
  531. signal(SIGALRM, oldhandler);
  532. alarm(oldalarm);
  533. DPRINTF("Timeout=%d, len=%d\n", dns_caught_signal, i);
  534. if (dns_caught_signal)
  535. /* timed out, so retry send and receive,
  536. to next nameserver on queue */
  537. goto again;
  538. if (i < HFIXEDSZ)
  539. /* too short ! */
  540. goto again;
  541. decode_header(packet, &h);
  542. DPRINTF("id = %d, qr = %d\n", h.id, h.qr);
  543. if ((h.id != id) || (!h.qr))
  544. /* unsolicited */
  545. goto again;
  546. DPRINTF("Got response %s\n", "(i think)!");
  547. DPRINTF("qrcount=%d,ancount=%d,nscount=%d,arcount=%d\n",
  548. h.qdcount, h.ancount, h.nscount, h.arcount);
  549. DPRINTF("opcode=%d,aa=%d,tc=%d,rd=%d,ra=%d,rcode=%d\n",
  550. h.opcode, h.aa, h.tc, h.rd, h.ra, h.rcode);
  551. if ((h.rcode) || (h.ancount < 1)) {
  552. /* negative result, not present */
  553. goto again;
  554. }
  555. pos = HFIXEDSZ;
  556. for (j = 0; j < h.qdcount; j++) {
  557. DPRINTF("Skipping question %d at %d\n", j, pos);
  558. i = length_question(packet, pos);
  559. DPRINTF("Length of question %d is %d\n", j, i);
  560. if (i < 0)
  561. goto again;
  562. pos += i;
  563. }
  564. DPRINTF("Decoding answer at pos %d\n", pos);
  565. for (j=0;j<h.ancount;j++)
  566. {
  567. i = decode_answer(packet, pos, a);
  568. if (i<0) {
  569. DPRINTF("failed decode %d\n", i);
  570. goto again;
  571. }
  572. /* For all but T_SIG, accept first answer */
  573. if (a->atype != T_SIG)
  574. break;
  575. DPRINTF("skipping T_SIG %d\n", i);
  576. free(a->dotted);
  577. pos += i;
  578. }
  579. DPRINTF("Answer name = |%s|\n", a->dotted);
  580. DPRINTF("Answer type = |%d|\n", a->atype);
  581. close(fd);
  582. if (outpacket)
  583. *outpacket = packet;
  584. else
  585. free(packet);
  586. free(lookup);
  587. return (0); /* success! */
  588. tryall:
  589. /* if there are other nameservers, give them a go,
  590. otherwise return with error */
  591. variant = 0;
  592. if (retries >= nscount*(searchdomains+1))
  593. goto fail;
  594. again:
  595. /* if there are searchdomains, try them or fallback as passed */
  596. if (variant < searchdomains) {
  597. /* next search */
  598. variant++;
  599. } else {
  600. /* next server, first search */
  601. ns = (ns + 1) % nscount;
  602. variant = 0;
  603. }
  604. }
  605. fail:
  606. if (fd != -1)
  607. close(fd);
  608. if (lookup)
  609. free(lookup);
  610. if (packet)
  611. free(packet);
  612. return -1;
  613. }
  614. #endif
  615. #ifdef L_resolveaddress
  616. int resolve_address(const char *address, int nscount,
  617. char **nsip, struct in_addr *in)
  618. {
  619. unsigned char *packet;
  620. struct resolv_answer a;
  621. char temp[256];
  622. int i;
  623. int nest = 0;
  624. if (!address || !in)
  625. return -1;
  626. strncpy(temp, address, sizeof(temp));
  627. for (;;) {
  628. i = dns_lookup(temp, T_A, nscount, nsip, &packet, &a);
  629. if (i < 0)
  630. return -1;
  631. free(a.dotted);
  632. if (a.atype == T_CNAME) { /* CNAME */
  633. DPRINTF("Got a CNAME in resolve_address()\n");
  634. i = decode_dotted(packet, a.rdoffset, temp, sizeof(temp));
  635. free(packet);
  636. if (i < 0)
  637. return -1;
  638. if (++nest > MAX_RECURSE)
  639. return -1;
  640. continue;
  641. } else if (a.atype == T_A) { /* ADDRESS */
  642. free(packet);
  643. break;
  644. } else {
  645. free(packet);
  646. return -1;
  647. }
  648. }
  649. if (in)
  650. memcpy(in, a.rdata, INADDRSZ); /* IPv4 T_A */
  651. return 0;
  652. }
  653. #endif
  654. #ifdef L_resolvemailbox
  655. int resolve_mailbox(const char *address, int nscount,
  656. char **nsip, struct in_addr *in)
  657. {
  658. struct resolv_answer a;
  659. unsigned char *packet;
  660. char temp[256];
  661. int nest = 0;
  662. int i;
  663. if (!address || !in)
  664. return -1;
  665. /* look up mail exchange */
  666. i = dns_lookup(address, T_MX, nscount, nsip, &packet, &a);
  667. strncpy(temp, address, sizeof(temp));
  668. if (i >= 0) {
  669. i = decode_dotted(packet, a.rdoffset+2, temp, sizeof(temp));
  670. free(packet);
  671. }
  672. for (;;) {
  673. i = dns_lookup(temp, T_A, nscount, nsip, &packet, &a);
  674. if (i < 0)
  675. return -1;
  676. free(a.dotted);
  677. if (a.atype == T_CNAME) { /* CNAME */
  678. DPRINTF("Got a CNAME in resolve_mailbox()\n");
  679. i = decode_dotted(packet, a.rdoffset, temp, sizeof(temp));
  680. free(packet);
  681. if (i < 0)
  682. return i;
  683. if (++nest > MAX_RECURSE)
  684. return -1;
  685. continue;
  686. } else if (a.atype == T_A) { /* ADDRESS */
  687. free(packet);
  688. break;
  689. } else {
  690. free(packet);
  691. return -1;
  692. }
  693. }
  694. if (in)
  695. memcpy(in, a.rdata, INADDRSZ); /* IPv4 */
  696. return 0;
  697. }
  698. #endif
  699. #ifdef L_opennameservers
  700. int nameservers;
  701. char * nameserver[MAX_SERVERS];
  702. int searchdomains;
  703. char * searchdomain[MAX_SEARCH];
  704. /*
  705. * we currently read formats not quite the same as that on normal
  706. * unix systems, we can have a list of nameservers after the keyword.
  707. */
  708. int open_nameservers()
  709. {
  710. FILE *fp;
  711. int i;
  712. #define RESOLV_ARGS 5
  713. char szBuffer[128], *p, *argv[RESOLV_ARGS];
  714. int argc;
  715. if (nameservers > 0)
  716. return 0;
  717. if ((fp = fopen("/etc/resolv.conf", "r")) ||
  718. (fp = fopen("/etc/config/resolv.conf", "r"))) {
  719. while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
  720. for (p = szBuffer; *p && isspace(*p); p++)
  721. /* skip white space */;
  722. if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */
  723. continue;
  724. argc = 0;
  725. while (*p && argc < RESOLV_ARGS) {
  726. argv[argc++] = p;
  727. while (*p && !isspace(*p) && *p != '\n')
  728. p++;
  729. while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */
  730. *p++ = '\0';
  731. }
  732. if (strcmp(argv[0], "nameserver") == 0) {
  733. for (i = 1; i < argc && nameservers < MAX_SERVERS; i++) {
  734. nameserver[nameservers++] = strdup(argv[i]);
  735. DPRINTF("adding nameserver %s\n", argv[i]);
  736. }
  737. }
  738. /* domain and search are mutually exclusive, the last one wins */
  739. if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) {
  740. while (searchdomains > 0) {
  741. free(searchdomain[--searchdomains]);
  742. searchdomain[searchdomains] = NULL;
  743. }
  744. for (i=1; i < argc && searchdomains < MAX_SEARCH; i++) {
  745. searchdomain[searchdomains++] = strdup(argv[i]);
  746. DPRINTF("adding search %s\n", argv[i]);
  747. }
  748. }
  749. }
  750. fclose(fp);
  751. } else {
  752. DPRINTF("failed to open %s\n", "resolv.conf");
  753. }
  754. DPRINTF("nameservers = %d\n", nameservers);
  755. return 0;
  756. }
  757. #endif
  758. #ifdef L_closenameservers
  759. void close_nameservers(void)
  760. {
  761. while (nameservers > 0) {
  762. free(nameserver[--nameservers]);
  763. nameserver[nameservers] = NULL;
  764. }
  765. while (searchdomains > 0) {
  766. free(searchdomain[--searchdomains]);
  767. searchdomain[searchdomains] = NULL;
  768. }
  769. }
  770. #endif
  771. #ifdef L_resolvename
  772. const char *resolve_name(const char *name, int mailbox)
  773. {
  774. struct in_addr in;
  775. int i;
  776. /* shortcut: is it a valid IP address to begin with? */
  777. if (inet_aton(name, &in))
  778. return name;
  779. open_nameservers();
  780. DPRINTF("looking up '%s', mailbox=%d, nameservers=%d\n",
  781. name, mailbox, nameservers);
  782. if (mailbox)
  783. i = resolve_mailbox(name, nameservers, nameserver, &in);
  784. else
  785. i = resolve_address(name, nameservers, nameserver, &in);
  786. if (i < 0)
  787. return 0;
  788. DPRINTF("success = '%s'\n", inet_ntoa(in));
  789. return inet_ntoa(in);
  790. }
  791. #endif
  792. #ifdef L_gethostbyname
  793. struct hostent *gethostbyname(const char *name)
  794. {
  795. static struct hostent h;
  796. static char namebuf[256];
  797. static struct in_addr in;
  798. static struct in_addr *addr_list[2];
  799. struct hostent *hp;
  800. unsigned char *packet;
  801. struct resolv_answer a;
  802. int i;
  803. int nest = 0;
  804. open_nameservers();
  805. if (!name)
  806. return 0;
  807. if ((hp = get_hosts_byname(name, AF_INET))) /* do /etc/hosts first */
  808. return(hp);
  809. memset(&h, 0, sizeof(h));
  810. addr_list[0] = &in;
  811. addr_list[1] = 0;
  812. strncpy(namebuf, name, sizeof(namebuf));
  813. /* First check if this is already an address */
  814. if (inet_aton(name, &in)) {
  815. h.h_name = namebuf;
  816. h.h_addrtype = AF_INET;
  817. h.h_length = sizeof(in);
  818. h.h_addr_list = (char **) addr_list;
  819. return &h;
  820. }
  821. for (;;) {
  822. i = dns_lookup(namebuf, 1, nameservers, nameserver, &packet, &a);
  823. if (i < 0)
  824. return 0;
  825. strncpy(namebuf, a.dotted, sizeof(namebuf));
  826. free(a.dotted);
  827. if (a.atype == T_CNAME) { /* CNAME */
  828. DPRINTF("Got a CNAME in gethostbyname()\n");
  829. i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf));
  830. free(packet);
  831. if (i < 0)
  832. return 0;
  833. if (++nest > MAX_RECURSE)
  834. return 0;
  835. continue;
  836. } else if (a.atype == T_A) { /* ADDRESS */
  837. memcpy(&in, a.rdata, sizeof(in));
  838. h.h_name = namebuf;
  839. h.h_addrtype = AF_INET;
  840. h.h_length = sizeof(in);
  841. h.h_addr_list = (char **) addr_list;
  842. free(packet);
  843. break;
  844. } else {
  845. free(packet);
  846. return 0;
  847. }
  848. }
  849. return &h;
  850. }
  851. #endif
  852. #ifdef L_gethostbyname2
  853. #ifdef __UCLIBC_HAS_IPV6__
  854. /* TBD: Not the right place for defining these, I guess */
  855. const struct in6_addr in6addr_any =
  856. { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
  857. const struct in6_addr in6addr_loopback =
  858. { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } };
  859. #endif /* __UCLIBC_HAS_IPV6__ */
  860. struct hostent *gethostbyname2(const char *name, int family)
  861. {
  862. #ifndef __UCLIBC_HAS_IPV6__
  863. return family == AF_INET ? gethostbyname(name) : (struct hostent*)0;
  864. #else /* __UCLIBC_HAS_IPV6__ */
  865. static struct hostent h;
  866. static char namebuf[256];
  867. static struct in6_addr in;
  868. static struct in6_addr *addr_list[2];
  869. struct hostent *hp;
  870. unsigned char *packet;
  871. struct resolv_answer a;
  872. int i;
  873. int nest = 0;
  874. if (family == AF_INET)
  875. return gethostbyname(name);
  876. if (family != AF_INET6)
  877. return NULL;
  878. open_nameservers();
  879. if (!name)
  880. return 0;
  881. if ((hp = get_hosts_byname(name, family))) /* do /etc/hosts first */
  882. return(hp);
  883. memset(&h, 0, sizeof(h));
  884. addr_list[0] = &in;
  885. addr_list[1] = 0;
  886. strncpy(namebuf, name, sizeof(namebuf));
  887. /* First check if this is already an address */
  888. if (inet_pton(AF_INET6, name, &in)) {
  889. h.h_name = namebuf;
  890. h.h_addrtype = AF_INET6;
  891. h.h_length = sizeof(in);
  892. h.h_addr_list = (char **) addr_list;
  893. return &h;
  894. }
  895. for (;;) {
  896. i = dns_lookup(namebuf, T_AAAA, nameservers, nameserver, &packet, &a);
  897. if (i < 0)
  898. return 0;
  899. strncpy(namebuf, a.dotted, sizeof(namebuf));
  900. free(a.dotted);
  901. if (a.atype == T_CNAME) { /* CNAME */
  902. DPRINTF("Got a CNAME in gethostbyname()\n");
  903. i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf));
  904. free(packet);
  905. if (i < 0)
  906. return 0;
  907. if (++nest > MAX_RECURSE)
  908. return 0;
  909. continue;
  910. } else if (a.atype == T_AAAA) { /* ADDRESS */
  911. memcpy(&in, a.rdata, sizeof(in));
  912. h.h_name = namebuf;
  913. h.h_addrtype = AF_INET6;
  914. h.h_length = sizeof(in);
  915. h.h_addr_list = (char **) addr_list;
  916. free(packet);
  917. break;
  918. } else {
  919. free(packet);
  920. return 0;
  921. }
  922. }
  923. return &h;
  924. #endif /* __UCLIBC_HAS_IPV6__ */
  925. }
  926. #endif
  927. #ifdef L_getnetbyname
  928. struct netent * getnetbyname(const char * name)
  929. {
  930. return NULL;
  931. }
  932. #endif
  933. #ifdef L_res_init
  934. int res_init(void)
  935. {
  936. return(0);
  937. }
  938. #endif
  939. #ifdef L_res_query
  940. #ifndef MIN
  941. #define MIN(x, y) ((x) < (y) ? (x) : (y))
  942. #endif
  943. int res_query(const char *dname, int class, int type,
  944. unsigned char *answer, int anslen)
  945. {
  946. unsigned char * packet = 0;
  947. struct resolv_answer a;
  948. int i;
  949. open_nameservers();
  950. if (!dname || class != 1 /* CLASS_IN */)
  951. return(-1);
  952. memset((char *) &a, '\0', sizeof(a));
  953. i = dns_lookup(dname, type, nameservers, nameserver, &packet, &a);
  954. if (i < 0)
  955. return(-1);
  956. free(a.dotted);
  957. if (a.atype == type) { /* CNAME*/
  958. if (anslen && answer)
  959. memcpy(answer, a.rdata, MIN(anslen, a.rdlength));
  960. if (packet)
  961. free(packet);
  962. return(MIN(anslen, a.rdlength));
  963. }
  964. if (packet)
  965. free(packet);
  966. return 0;
  967. }
  968. #endif
  969. #ifdef L_gethostbyaddr
  970. struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type)
  971. {
  972. static struct hostent h;
  973. static char namebuf[256];
  974. static struct in_addr in;
  975. static struct in_addr *addr_list[2];
  976. #ifdef __UCLIBC_HAS_IPV6__
  977. char *qp;
  978. static struct in6_addr in6;
  979. static struct in6_addr *addr_list6[2];
  980. #endif /* __UCLIBC_HAS_IPV6__ */
  981. struct hostent *hp;
  982. unsigned char *packet;
  983. struct resolv_answer a;
  984. int i;
  985. int nest = 0;
  986. if (!addr)
  987. return 0;
  988. switch (type) {
  989. case AF_INET:
  990. if (len != sizeof(struct in_addr))
  991. return 0;
  992. break;
  993. #ifdef __UCLIBC_HAS_IPV6__
  994. case AF_INET6:
  995. if (len != sizeof(struct in6_addr))
  996. return 0;
  997. break;
  998. #endif /* __UCLIBC_HAS_IPV6__ */
  999. default:
  1000. return 0;
  1001. }
  1002. if ((hp = get_hosts_byaddr(addr, len, type))) /* do /etc/hosts first */
  1003. return(hp);
  1004. open_nameservers();
  1005. memset(&h, 0, sizeof(h));
  1006. if(type == AF_INET) {
  1007. unsigned char *tmp_addr = (unsigned char *)addr;
  1008. memcpy(&in.s_addr, addr, len);
  1009. addr_list[0] = &in;
  1010. sprintf(namebuf, "%u.%u.%u.%u.in-addr.arpa",
  1011. tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]);
  1012. #ifdef __UCLIBC_HAS_IPV6__
  1013. } else {
  1014. memcpy(&in6.s6_addr, addr, len);
  1015. addr_list6[0] = &in6;
  1016. qp = namebuf;
  1017. for (i = len - 1; i >= 0; i--) {
  1018. qp += sprintf(qp, "%x.%x.", in6.s6_addr[i] & 0xf,
  1019. (in6.s6_addr[i] >> 4) & 0xf);
  1020. }
  1021. strcpy(qp, "ip6.int");
  1022. #endif /* __UCLIBC_HAS_IPV6__ */
  1023. }
  1024. addr_list[1] = 0;
  1025. for (;;) {
  1026. i = dns_lookup(namebuf, T_PTR, nameservers, nameserver, &packet, &a);
  1027. if (i < 0)
  1028. return 0;
  1029. strncpy(namebuf, a.dotted, sizeof(namebuf));
  1030. free(a.dotted);
  1031. if (a.atype == T_CNAME) { /* CNAME */
  1032. DPRINTF("Got a CNAME in gethostbyaddr()\n");
  1033. i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf));
  1034. free(packet);
  1035. if (i < 0)
  1036. return 0;
  1037. if (++nest > MAX_RECURSE)
  1038. return 0;
  1039. continue;
  1040. } else if (a.atype == T_PTR) { /* ADDRESS */
  1041. i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf));
  1042. free(packet);
  1043. h.h_name = namebuf;
  1044. h.h_addrtype = type;
  1045. if(type == AF_INET) {
  1046. h.h_length = sizeof(in);
  1047. #ifdef __UCLIBC_HAS_IPV6__
  1048. } else {
  1049. h.h_length = sizeof(in6);
  1050. #endif /* __UCLIBC_HAS_IPV6__ */
  1051. }
  1052. h.h_addr_list = (char **) addr_list;
  1053. break;
  1054. } else {
  1055. free(packet);
  1056. return 0;
  1057. }
  1058. }
  1059. return &h;
  1060. }
  1061. #endif
  1062. #ifdef L_read_etc_hosts
  1063. struct hostent * read_etc_hosts(const char * name, int type, int ip)
  1064. {
  1065. static struct hostent h;
  1066. static struct in_addr in;
  1067. static struct in_addr *addr_list[2];
  1068. #ifdef __UCLIBC_HAS_IPV6__
  1069. static struct in6_addr in6;
  1070. static struct in6_addr *addr_list6[2];
  1071. #endif /* __UCLIBC_HAS_IPV6__ */
  1072. static char line[80];
  1073. FILE *fp;
  1074. char *cp;
  1075. #define MAX_ALIAS 5
  1076. char *alias[MAX_ALIAS];
  1077. int aliases, i;
  1078. if ((fp = fopen("/etc/hosts", "r")) == NULL &&
  1079. (fp = fopen("/etc/config/hosts", "r")) == NULL)
  1080. return((struct hostent *) NULL);
  1081. while (fgets(line, sizeof(line), fp)) {
  1082. if ((cp = strchr(line, '#')))
  1083. *cp = '\0';
  1084. aliases = 0;
  1085. cp = line;
  1086. while (*cp) {
  1087. while (*cp && isspace(*cp))
  1088. *cp++ = '\0';
  1089. if (!*cp)
  1090. continue;
  1091. if (aliases < MAX_ALIAS)
  1092. alias[aliases++] = cp;
  1093. while (*cp && !isspace(*cp))
  1094. cp++;
  1095. }
  1096. if (aliases < 2)
  1097. continue; /* syntax error really */
  1098. if (ip) {
  1099. if (strcmp(name, alias[0]) != 0)
  1100. continue;
  1101. } else {
  1102. for (i = 1; i < aliases; i++)
  1103. if (strcasecmp(name, alias[i]) == 0)
  1104. break;
  1105. if (i >= aliases)
  1106. continue;
  1107. }
  1108. if (type == AF_INET && inet_pton(AF_INET, alias[0], &in) > 0) {
  1109. addr_list[0] = &in;
  1110. addr_list[1] = 0;
  1111. h.h_name = alias[1];
  1112. h.h_addrtype = AF_INET;
  1113. h.h_length = sizeof(in);
  1114. h.h_addr_list = (char**) addr_list;
  1115. #ifdef __UCLIBC_HAS_IPV6__
  1116. } else if (type == AF_INET6 && inet_pton(AF_INET6, alias[0], &in6) > 0) {
  1117. addr_list6[0] = &in6;
  1118. addr_list6[1] = 0;
  1119. h.h_name = alias[1];
  1120. h.h_addrtype = AF_INET6;
  1121. h.h_length = sizeof(in6);
  1122. h.h_addr_list = (char**) addr_list6;
  1123. #endif /* __UCLIBC_HAS_IPV6__ */
  1124. } else {
  1125. break; /* bad ip address */
  1126. }
  1127. fclose(fp);
  1128. return(&h);
  1129. }
  1130. fclose(fp);
  1131. return((struct hostent *) NULL);
  1132. }
  1133. #endif
  1134. #ifdef L_get_hosts_byname
  1135. struct hostent * get_hosts_byname(const char * name, int type)
  1136. {
  1137. return(read_etc_hosts(name, type, 0));
  1138. }
  1139. #endif
  1140. #ifdef L_get_hosts_byaddr
  1141. struct hostent * get_hosts_byaddr(const char * addr, int len, int type)
  1142. {
  1143. #ifndef __UCLIBC_HAS_IPV6__
  1144. char ipaddr[INET_ADDRSTRLEN];
  1145. #else
  1146. char ipaddr[INET6_ADDRSTRLEN];
  1147. #endif /* __UCLIBC_HAS_IPV6__ */
  1148. switch (type) {
  1149. case AF_INET:
  1150. if (len != sizeof(struct in_addr))
  1151. return 0;
  1152. break;
  1153. #ifdef __UCLIBC_HAS_IPV6__
  1154. case AF_INET6:
  1155. if (len != sizeof(struct in6_addr))
  1156. return 0;
  1157. break;
  1158. #endif /* __UCLIBC_HAS_IPV6__ */
  1159. default:
  1160. return 0;
  1161. }
  1162. inet_ntop(type, addr, ipaddr, sizeof(ipaddr));
  1163. return(read_etc_hosts(ipaddr, type, 1));
  1164. }
  1165. #endif
  1166. #ifdef L_getnameinfo
  1167. #ifndef min
  1168. # define min(x,y) (((x) > (y)) ? (y) : (x))
  1169. #endif /* min */
  1170. int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
  1171. socklen_t hostlen, char *serv, socklen_t servlen,
  1172. unsigned int flags)
  1173. {
  1174. int serrno = errno;
  1175. int ok = 0;
  1176. struct hostent *h = NULL;
  1177. char domain[256];
  1178. if (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|NI_NAMEREQD|NI_DGRAM))
  1179. return EAI_BADFLAGS;
  1180. if (sa == NULL || addrlen < sizeof (sa_family_t))
  1181. return EAI_FAMILY;
  1182. switch (sa->sa_family) {
  1183. case AF_LOCAL:
  1184. break;
  1185. case AF_INET:
  1186. if (addrlen < sizeof (struct sockaddr_in))
  1187. return EAI_FAMILY;
  1188. break;
  1189. #ifdef __UCLIBC_HAS_IPV6__
  1190. case AF_INET6:
  1191. if (addrlen < sizeof (struct sockaddr_in6))
  1192. return EAI_FAMILY;
  1193. break;
  1194. #endif /* __UCLIBC_HAS_IPV6__ */
  1195. default:
  1196. return EAI_FAMILY;
  1197. }
  1198. if (host != NULL && hostlen > 0)
  1199. switch (sa->sa_family) {
  1200. case AF_INET:
  1201. #ifdef __UCLIBC_HAS_IPV6__
  1202. case AF_INET6:
  1203. #endif /* __UCLIBC_HAS_IPV6__ */
  1204. if (!(flags & NI_NUMERICHOST)) {
  1205. #ifdef __UCLIBC_HAS_IPV6__
  1206. if (sa->sa_family == AF_INET6)
  1207. h = gethostbyaddr ((const void *) &(((const struct sockaddr_in6 *) sa)->sin6_addr),
  1208. sizeof(struct in6_addr), AF_INET6);
  1209. else
  1210. #endif /* __UCLIBC_HAS_IPV6__ */
  1211. h = gethostbyaddr ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr),
  1212. sizeof(struct in_addr), AF_INET);
  1213. if (h) {
  1214. char *c;
  1215. if ((flags & NI_NOFQDN)
  1216. && (getdomainname (domain, sizeof(domain)) == 0)
  1217. && (c = strstr (h->h_name, domain))
  1218. && (c != h->h_name) && (*(--c) == '.')) {
  1219. strncpy (host, h->h_name,
  1220. min(hostlen, (size_t) (c - h->h_name)));
  1221. host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0';
  1222. ok = 1;
  1223. } else {
  1224. strncpy (host, h->h_name, hostlen);
  1225. ok = 1;
  1226. }
  1227. }
  1228. }
  1229. if (!ok) {
  1230. if (flags & NI_NAMEREQD) {
  1231. errno = serrno;
  1232. return EAI_NONAME;
  1233. } else {
  1234. const char *c;
  1235. #ifdef __UCLIBC_HAS_IPV6__
  1236. if (sa->sa_family == AF_INET6) {
  1237. const struct sockaddr_in6 *sin6p;
  1238. sin6p = (const struct sockaddr_in6 *) sa;
  1239. c = inet_ntop (AF_INET6,
  1240. (const void *) &sin6p->sin6_addr, host, hostlen);
  1241. #if 0
  1242. /* Does scope id need to be supported? */
  1243. uint32_t scopeid;
  1244. scopeid = sin6p->sin6_scope_id;
  1245. if (scopeid != 0) {
  1246. /* Buffer is >= IFNAMSIZ+1. */
  1247. char scopebuf[IFNAMSIZ + 1];
  1248. char *scopeptr;
  1249. int ni_numericscope = 0;
  1250. size_t real_hostlen = __strnlen (host, hostlen);
  1251. size_t scopelen = 0;
  1252. scopebuf[0] = SCOPE_DELIMITER;
  1253. scopebuf[1] = '\0';
  1254. scopeptr = &scopebuf[1];
  1255. if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
  1256. || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) {
  1257. if (if_indextoname (scopeid, scopeptr) == NULL)
  1258. ++ni_numericscope;
  1259. else
  1260. scopelen = strlen (scopebuf);
  1261. } else {
  1262. ++ni_numericscope;
  1263. }
  1264. if (ni_numericscope)
  1265. scopelen = 1 + snprintf (scopeptr,
  1266. (scopebuf
  1267. + sizeof scopebuf
  1268. - scopeptr),
  1269. "%u", scopeid);
  1270. if (real_hostlen + scopelen + 1 > hostlen)
  1271. return EAI_SYSTEM;
  1272. memcpy (host + real_hostlen, scopebuf, scopelen + 1);
  1273. }
  1274. #endif
  1275. } else
  1276. #endif /* __UCLIBC_HAS_IPV6__ */
  1277. c = inet_ntop (AF_INET,
  1278. (const void *) &(((const struct sockaddr_in *) sa)->sin_addr),
  1279. host, hostlen);
  1280. if (c == NULL) {
  1281. errno = serrno;
  1282. return EAI_SYSTEM;
  1283. }
  1284. }
  1285. ok = 1;
  1286. }
  1287. break;
  1288. case AF_LOCAL:
  1289. if (!(flags & NI_NUMERICHOST)) {
  1290. struct utsname utsname;
  1291. if (!uname (&utsname)) {
  1292. strncpy (host, utsname.nodename, hostlen);
  1293. break;
  1294. };
  1295. };
  1296. if (flags & NI_NAMEREQD) {
  1297. errno = serrno;
  1298. return EAI_NONAME;
  1299. }
  1300. strncpy (host, "localhost", hostlen);
  1301. break;
  1302. default:
  1303. return EAI_FAMILY;
  1304. }
  1305. if (serv && (servlen > 0)) {
  1306. switch (sa->sa_family) {
  1307. case AF_INET:
  1308. #ifdef __UCLIBC_HAS_IPV6__
  1309. case AF_INET6:
  1310. #endif /* __UCLIBC_HAS_IPV6__ */
  1311. if (!(flags & NI_NUMERICSERV)) {
  1312. struct servent *s;
  1313. s = getservbyport (((const struct sockaddr_in *) sa)->sin_port,
  1314. ((flags & NI_DGRAM) ? "udp" : "tcp"));
  1315. if (s) {
  1316. strncpy (serv, s->s_name, servlen);
  1317. break;
  1318. }
  1319. }
  1320. snprintf (serv, servlen, "%d",
  1321. ntohs (((const struct sockaddr_in *) sa)->sin_port));
  1322. break;
  1323. case AF_LOCAL:
  1324. strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
  1325. break;
  1326. }
  1327. }
  1328. if (host && (hostlen > 0))
  1329. host[hostlen-1] = 0;
  1330. if (serv && (servlen > 0))
  1331. serv[servlen-1] = 0;
  1332. errno = serrno;
  1333. return 0;
  1334. }
  1335. #endif