resolv.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328
  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. */
  40. #define __FORCE_GLIBC__
  41. #include <features.h>
  42. #include <string.h>
  43. #include <stdio.h>
  44. #include <signal.h>
  45. #include <errno.h>
  46. #include <sys/socket.h>
  47. #include <sys/types.h>
  48. #include <netinet/in.h>
  49. #include <arpa/inet.h>
  50. #include <stdlib.h>
  51. #include <unistd.h>
  52. #include <cfgfile.h>
  53. #include <resolv.h>
  54. #include <netdb.h>
  55. #include <ctype.h>
  56. #include <arpa/nameser.h>
  57. #define MAX_RECURSE 5
  58. #define REPLY_TIMEOUT 10
  59. #define MAX_RETRIES 15
  60. #define MAX_SERVERS 3
  61. #define MAX_SEARCH 4
  62. #undef DEBUG
  63. /*#define DEBUG*/
  64. #ifdef DEBUG
  65. #define DPRINTF(X,args...) fprintf(stderr, X, ##args)
  66. #else
  67. #define DPRINTF(X,args...)
  68. #endif /* DEBUG */
  69. extern int nameservers;
  70. extern char * nameserver[MAX_SERVERS];
  71. extern int searchdomains;
  72. extern char * searchdomain[MAX_SEARCH];
  73. extern struct hostent * get_hosts_byname(const char * name);
  74. extern struct hostent * get_hosts_byaddr(const char * addr, int len, int type);
  75. extern struct hostent * read_etc_hosts(const char * name, int ip);
  76. extern int resolve_address(const char * address, int nscount,
  77. char ** nsip, struct in_addr * in);
  78. extern int resolve_mailbox(const char * address, int nscount,
  79. char ** nsip, struct in_addr * in);
  80. extern int dns_lookup(const char * name, int type, int nscount,
  81. char ** nsip, unsigned char ** outpacket, struct resolv_answer * a);
  82. #ifdef L_encodeh
  83. int encode_header(struct resolv_header *h, unsigned char *dest, int maxlen)
  84. {
  85. if (maxlen < HFIXEDSZ)
  86. return -1;
  87. dest[0] = (h->id & 0xff00) >> 8;
  88. dest[1] = (h->id & 0x00ff) >> 0;
  89. dest[2] = (h->qr ? 0x80 : 0) |
  90. ((h->opcode & 0x0f) << 3) |
  91. (h->aa ? 0x04 : 0) |
  92. (h->tc ? 0x02 : 0) |
  93. (h->rd ? 0x01 : 0);
  94. dest[3] = (h->ra ? 0x80 : 0) | (h->rcode & 0x0f);
  95. dest[4] = (h->qdcount & 0xff00) >> 8;
  96. dest[5] = (h->qdcount & 0x00ff) >> 0;
  97. dest[6] = (h->ancount & 0xff00) >> 8;
  98. dest[7] = (h->ancount & 0x00ff) >> 0;
  99. dest[8] = (h->nscount & 0xff00) >> 8;
  100. dest[9] = (h->nscount & 0x00ff) >> 0;
  101. dest[10] = (h->arcount & 0xff00) >> 8;
  102. dest[11] = (h->arcount & 0x00ff) >> 0;
  103. return HFIXEDSZ;
  104. }
  105. #endif
  106. #ifdef L_decodeh
  107. int decode_header(unsigned char *data, struct resolv_header *h)
  108. {
  109. h->id = (data[0] << 8) | data[1];
  110. h->qr = (data[2] & 0x80) ? 1 : 0;
  111. h->opcode = (data[2] >> 3) & 0x0f;
  112. h->aa = (data[2] & 0x04) ? 1 : 0;
  113. h->tc = (data[2] & 0x02) ? 1 : 0;
  114. h->rd = (data[2] & 0x01) ? 1 : 0;
  115. h->ra = (data[3] & 0x80) ? 1 : 0;
  116. h->rcode = data[3] & 0x0f;
  117. h->qdcount = (data[4] << 8) | data[5];
  118. h->ancount = (data[6] << 8) | data[7];
  119. h->nscount = (data[8] << 8) | data[9];
  120. h->arcount = (data[10] << 8) | data[11];
  121. return HFIXEDSZ;
  122. }
  123. #endif
  124. #ifdef L_encoded
  125. /* Encode a dotted string into nameserver transport-level encoding.
  126. This routine is fairly dumb, and doesn't attempt to compress
  127. the data */
  128. int encode_dotted(const char *dotted, unsigned char *dest, int maxlen)
  129. {
  130. int used = 0;
  131. while (dotted && *dotted) {
  132. char *c = strchr(dotted, '.');
  133. int l = c ? c - dotted : strlen(dotted);
  134. if (l >= (maxlen - used - 1))
  135. return -1;
  136. dest[used++] = l;
  137. memcpy(dest + used, dotted, l);
  138. used += l;
  139. if (c)
  140. dotted = c + 1;
  141. else
  142. break;
  143. }
  144. if (maxlen < 1)
  145. return -1;
  146. dest[used++] = 0;
  147. return used;
  148. }
  149. #endif
  150. #ifdef L_decoded
  151. /* Decode a dotted string from nameserver transport-level encoding.
  152. This routine understands compressed data. */
  153. int decode_dotted(const unsigned char *data, int offset,
  154. char *dest, int maxlen)
  155. {
  156. int l;
  157. int measure = 1;
  158. int total = 0;
  159. int used = 0;
  160. if (!data)
  161. return -1;
  162. while ((l=data[offset++])) {
  163. if (measure)
  164. total++;
  165. if ((l & 0xc0) == (0xc0)) {
  166. if (measure)
  167. total++;
  168. /* compressed item, redirect */
  169. offset = ((l & 0x3f) << 8) | data[offset];
  170. measure = 0;
  171. continue;
  172. }
  173. if ((used + l + 1) >= maxlen)
  174. return -1;
  175. memcpy(dest + used, data + offset, l);
  176. offset += l;
  177. used += l;
  178. if (measure)
  179. total += l;
  180. if (data[offset] != 0)
  181. dest[used++] = '.';
  182. else
  183. dest[used++] = '\0';
  184. }
  185. DPRINTF("Total decode len = %d\n", total);
  186. return total;
  187. }
  188. #endif
  189. #ifdef L_lengthd
  190. int length_dotted(const unsigned char *data, int offset)
  191. {
  192. int orig_offset = offset;
  193. int l;
  194. if (!data)
  195. return -1;
  196. while ((l = data[offset++])) {
  197. if ((l & 0xc0) == (0xc0)) {
  198. offset++;
  199. break;
  200. }
  201. offset += l;
  202. }
  203. return offset - orig_offset;
  204. }
  205. #endif
  206. #ifdef L_encodeq
  207. int encode_question(struct resolv_question *q,
  208. unsigned char *dest, int maxlen)
  209. {
  210. int i;
  211. i = encode_dotted(q->dotted, dest, maxlen);
  212. if (i < 0)
  213. return i;
  214. dest += i;
  215. maxlen -= i;
  216. if (maxlen < 4)
  217. return -1;
  218. dest[0] = (q->qtype & 0xff00) >> 8;
  219. dest[1] = (q->qtype & 0x00ff) >> 0;
  220. dest[2] = (q->qclass & 0xff00) >> 8;
  221. dest[3] = (q->qclass & 0x00ff) >> 0;
  222. return i + 4;
  223. }
  224. #endif
  225. #ifdef L_decodeq
  226. int decode_question(unsigned char *message, int offset,
  227. struct resolv_question *q)
  228. {
  229. char temp[256];
  230. int i;
  231. i = decode_dotted(message, offset, temp, sizeof(temp));
  232. if (i < 0)
  233. return i;
  234. offset += i;
  235. q->dotted = strdup(temp);
  236. q->qtype = (message[offset + 0] << 8) | message[offset + 1];
  237. q->qclass = (message[offset + 2] << 8) | message[offset + 3];
  238. return i + 4;
  239. }
  240. #endif
  241. #ifdef L_lengthq
  242. int length_question(unsigned char *message, int offset)
  243. {
  244. int i;
  245. i = length_dotted(message, offset);
  246. if (i < 0)
  247. return i;
  248. return i + 4;
  249. }
  250. #endif
  251. #ifdef L_encodea
  252. int encode_answer(struct resolv_answer *a, unsigned char *dest, int maxlen)
  253. {
  254. int i;
  255. i = encode_dotted(a->dotted, dest, maxlen);
  256. if (i < 0)
  257. return i;
  258. dest += i;
  259. maxlen -= i;
  260. if (maxlen < (RRFIXEDSZ+a->rdlength))
  261. return -1;
  262. *dest++ = (a->atype & 0xff00) >> 8;
  263. *dest++ = (a->atype & 0x00ff) >> 0;
  264. *dest++ = (a->aclass & 0xff00) >> 8;
  265. *dest++ = (a->aclass & 0x00ff) >> 0;
  266. *dest++ = (a->ttl & 0xff000000) >> 24;
  267. *dest++ = (a->ttl & 0x00ff0000) >> 16;
  268. *dest++ = (a->ttl & 0x0000ff00) >> 8;
  269. *dest++ = (a->ttl & 0x000000ff) >> 0;
  270. *dest++ = (a->rdlength & 0xff00) >> 8;
  271. *dest++ = (a->rdlength & 0x00ff) >> 0;
  272. memcpy(dest, a->rdata, a->rdlength);
  273. return i + RRFIXEDSZ + a->rdlength;
  274. }
  275. #endif
  276. #ifdef L_decodea
  277. int decode_answer(unsigned char *message, int offset,
  278. struct resolv_answer *a)
  279. {
  280. char temp[256];
  281. int i;
  282. i = decode_dotted(message, offset, temp, sizeof(temp));
  283. if (i < 0)
  284. return i;
  285. message += offset + i;
  286. a->dotted = strdup(temp);
  287. a->atype = (message[0] << 8) | message[1];
  288. message += 2;
  289. a->aclass = (message[0] << 8) | message[1];
  290. message += 2;
  291. a->ttl = (message[0] << 24) |
  292. (message[1] << 16) | (message[2] << 8) | (message[3] << 0);
  293. message += 4;
  294. a->rdlength = (message[0] << 8) | message[1];
  295. message += 2;
  296. a->rdata = message;
  297. a->rdoffset = offset + i + RRFIXEDSZ;
  298. DPRINTF("i=%d,rdlength=%d\n", i, a->rdlength);
  299. return i + RRFIXEDSZ + a->rdlength;
  300. }
  301. #endif
  302. #ifdef L_encodep
  303. int encode_packet(struct resolv_header *h,
  304. struct resolv_question **q,
  305. struct resolv_answer **an,
  306. struct resolv_answer **ns,
  307. struct resolv_answer **ar,
  308. unsigned char *dest, int maxlen)
  309. {
  310. int i, total = 0;
  311. int j;
  312. i = encode_header(h, dest, maxlen);
  313. if (i < 0)
  314. return i;
  315. dest += i;
  316. maxlen -= i;
  317. total += i;
  318. for (j = 0; j < h->qdcount; j++) {
  319. i = encode_question(q[j], dest, maxlen);
  320. if (i < 0)
  321. return i;
  322. dest += i;
  323. maxlen -= i;
  324. total += i;
  325. }
  326. for (j = 0; j < h->ancount; j++) {
  327. i = encode_answer(an[j], dest, maxlen);
  328. if (i < 0)
  329. return i;
  330. dest += i;
  331. maxlen -= i;
  332. total += i;
  333. }
  334. for (j = 0; j < h->nscount; j++) {
  335. i = encode_answer(ns[j], dest, maxlen);
  336. if (i < 0)
  337. return i;
  338. dest += i;
  339. maxlen -= i;
  340. total += i;
  341. }
  342. for (j = 0; j < h->arcount; j++) {
  343. i = encode_answer(ar[j], dest, maxlen);
  344. if (i < 0)
  345. return i;
  346. dest += i;
  347. maxlen -= i;
  348. total += i;
  349. }
  350. return total;
  351. }
  352. #endif
  353. #ifdef L_decodep
  354. int decode_packet(unsigned char *data, struct resolv_header *h)
  355. {
  356. return decode_header(data, h);
  357. }
  358. #endif
  359. #ifdef L_formquery
  360. int form_query(int id, const char *name, int type, unsigned char *packet,
  361. int maxlen)
  362. {
  363. struct resolv_header h;
  364. struct resolv_question q;
  365. int i, j;
  366. memset(&h, 0, sizeof(h));
  367. h.id = id;
  368. h.qdcount = 1;
  369. q.dotted = (char *) name;
  370. q.qtype = type;
  371. q.qclass = C_IN; /* CLASS_IN */
  372. i = encode_header(&h, packet, maxlen);
  373. if (i < 0)
  374. return i;
  375. j = encode_question(&q, packet + i, maxlen - i);
  376. if (j < 0)
  377. return j;
  378. return i + j;
  379. }
  380. #endif
  381. #ifdef L_dnslookup
  382. int dns_caught_signal = 0;
  383. void dns_catch_signal(int signo)
  384. {
  385. dns_caught_signal = 1;
  386. }
  387. int dns_lookup(const char *name, int type, int nscount, char **nsip,
  388. unsigned char **outpacket, struct resolv_answer *a)
  389. {
  390. static int id = 1;
  391. int i, j, len, fd, pos;
  392. static int ns = 0;
  393. struct sockaddr_in sa;
  394. #ifdef __UCLIBC_HAS_IPV6__
  395. struct sockaddr_in6 sa6;
  396. #endif /* __UCLIBC_HAS_IPV6__ */
  397. int oldalarm;
  398. __sighandler_t oldhandler;
  399. struct resolv_header h;
  400. struct resolv_question q;
  401. int retries = 0;
  402. unsigned char * packet = malloc(PACKETSZ);
  403. unsigned char * lookup = malloc(MAXDNAME);
  404. int variant = 0;
  405. #ifdef __UCLIBC_HAS_IPV6__
  406. int v6;
  407. #endif /* __UCLIBC_HAS_IPV6__ */
  408. fd = -1;
  409. if (!packet || !lookup || !nscount)
  410. goto fail;
  411. DPRINTF("Looking up type %d answer for '%s'\n", type, name);
  412. ns %= nscount;
  413. while (retries++ < MAX_RETRIES) {
  414. #ifdef __UCLIBC_HAS_IPV6__
  415. v6 = (inet_pton(AF_INET6, nsip[ns], &sa6.sin6_addr) > 0);
  416. #endif /* __UCLIBC_HAS_IPV6__ */
  417. if (fd != -1)
  418. close(fd);
  419. #ifndef __UCLIBC_HAS_IPV6__
  420. fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  421. #else /* __UCLIBC_HAS_IPV6__ */
  422. fd = socket(v6 ? AF_INET6 : AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  423. #endif /* __UCLIBC_HAS_IPV6__ */
  424. if (fd == -1)
  425. goto fail;
  426. memset(packet, 0, PACKETSZ);
  427. memset(&h, 0, sizeof(h));
  428. h.id = ++id;
  429. h.qdcount = 1;
  430. h.rd = 1;
  431. DPRINTF("encoding header\n", h.rd);
  432. i = encode_header(&h, packet, PACKETSZ);
  433. if (i < 0)
  434. goto fail;
  435. strncpy(lookup,name,MAXDNAME);
  436. if (variant < searchdomains && strchr(lookup, '.') == NULL)
  437. {
  438. strncat(lookup,".", MAXDNAME);
  439. strncat(lookup,searchdomain[variant], MAXDNAME);
  440. }
  441. DPRINTF("lookup name: %s\n", lookup);
  442. q.dotted = (char *)lookup;
  443. q.qtype = type;
  444. q.qclass = C_IN; /* CLASS_IN */
  445. j = encode_question(&q, packet+i, PACKETSZ-i);
  446. if (j < 0)
  447. goto fail;
  448. len = i + j;
  449. DPRINTF("On try %d, sending query to port %d of machine %s\n",
  450. retries, NAMESERVER_PORT, nsip[ns]);
  451. #ifndef __UCLIBC_HAS_IPV6__
  452. sa.sin_family = AF_INET;
  453. sa.sin_port = htons(NAMESERVER_PORT);
  454. sa.sin_addr.s_addr = inet_addr(nsip[ns]);
  455. #else /* __UCLIBC_HAS_IPV6__ */
  456. if (v6) {
  457. sa6.sin6_family = AF_INET6;
  458. sa6.sin6_port = htons(NAMESERVER_PORT);
  459. /* sa6.sin6_addr is already here */
  460. } else {
  461. sa.sin_family = AF_INET;
  462. sa.sin_port = htons(NAMESERVER_PORT);
  463. sa.sin_addr.s_addr = inet_addr(nsip[ns]);
  464. }
  465. #endif /* __UCLIBC_HAS_IPV6__ */
  466. #ifndef __UCLIBC_HAS_IPV6__
  467. if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
  468. #else /* __UCLIBC_HAS_IPV6__ */
  469. if (connect(fd, (struct sockaddr *) (v6 ? &sa6 : &sa),
  470. v6 ? sizeof(sa6) : sizeof(sa)) == -1) {
  471. #endif /* __UCLIBC_HAS_IPV6__ */
  472. if (errno == ENETUNREACH) {
  473. /* routing error, presume not transient */
  474. goto tryall;
  475. } else
  476. /* retry */
  477. continue;
  478. }
  479. DPRINTF("Transmitting packet of length %d, id=%d, qr=%d\n",
  480. len, h.id, h.qr);
  481. send(fd, packet, len, 0);
  482. dns_caught_signal = 0;
  483. oldalarm = alarm(REPLY_TIMEOUT);
  484. oldhandler = signal(SIGALRM, dns_catch_signal);
  485. i = recv(fd, packet, PACKETSZ, 0);
  486. alarm(0);
  487. signal(SIGALRM, oldhandler);
  488. alarm(oldalarm);
  489. DPRINTF("Timeout=%d, len=%d\n", dns_caught_signal, i);
  490. if (dns_caught_signal)
  491. /* timed out, so retry send and receive,
  492. to next nameserver on queue */
  493. goto again;
  494. if (i < HFIXEDSZ)
  495. /* too short ! */
  496. goto again;
  497. decode_header(packet, &h);
  498. DPRINTF("id = %d, qr = %d\n", h.id, h.qr);
  499. if ((h.id != id) || (!h.qr))
  500. /* unsolicited */
  501. goto again;
  502. DPRINTF("Got response %s\n", "(i think)!");
  503. DPRINTF("qrcount=%d,ancount=%d,nscount=%d,arcount=%d\n",
  504. h.qdcount, h.ancount, h.nscount, h.arcount);
  505. DPRINTF("opcode=%d,aa=%d,tc=%d,rd=%d,ra=%d,rcode=%d\n",
  506. h.opcode, h.aa, h.tc, h.rd, h.ra, h.rcode);
  507. if ((h.rcode) || (h.ancount < 1)) {
  508. /* negative result, not present */
  509. goto again;
  510. }
  511. pos = HFIXEDSZ;
  512. for (j = 0; j < h.qdcount; j++) {
  513. DPRINTF("Skipping question %d at %d\n", j, pos);
  514. i = length_question(packet, pos);
  515. DPRINTF("Length of question %d is %d\n", j, i);
  516. if (i < 0)
  517. goto again;
  518. pos += i;
  519. }
  520. DPRINTF("Decoding answer at pos %d\n", pos);
  521. for (j=0;j<h.ancount;j++)
  522. {
  523. i = decode_answer(packet, pos, a);
  524. if (i<0) {
  525. DPRINTF("failed decode %d\n", i);
  526. goto again;
  527. }
  528. /* For all but T_SIG, accept first answer */
  529. if (a->atype != T_SIG)
  530. break;
  531. DPRINTF("skipping T_SIG %d\n", i);
  532. free(a->dotted);
  533. pos += i;
  534. }
  535. DPRINTF("Answer name = |%s|\n", a->dotted);
  536. DPRINTF("Answer type = |%d|\n", a->atype);
  537. close(fd);
  538. if (outpacket)
  539. *outpacket = packet;
  540. else
  541. free(packet);
  542. return (0); /* success! */
  543. tryall:
  544. /* if there are other nameservers, give them a go,
  545. otherwise return with error */
  546. variant = 0;
  547. if (retries >= nscount*(searchdomains+1))
  548. goto fail;
  549. again:
  550. /* if there are searchdomains, try them or fallback as passed */
  551. if (variant < searchdomains) {
  552. /* next search */
  553. variant++;
  554. } else {
  555. /* next server, first search */
  556. ns = (ns + 1) % nscount;
  557. variant = 0;
  558. }
  559. }
  560. fail:
  561. if (fd != -1)
  562. close(fd);
  563. if (lookup)
  564. free(lookup);
  565. if (packet)
  566. free(packet);
  567. return -1;
  568. }
  569. #endif
  570. #ifdef L_resolveaddress
  571. int resolve_address(const char *address, int nscount,
  572. char **nsip, struct in_addr *in)
  573. {
  574. unsigned char *packet;
  575. struct resolv_answer a;
  576. char temp[256];
  577. int i;
  578. int nest = 0;
  579. if (!address || !in)
  580. return -1;
  581. strncpy(temp, address, sizeof(temp));
  582. for (;;) {
  583. i = dns_lookup(temp, T_A, nscount, nsip, &packet, &a);
  584. if (i < 0)
  585. return -1;
  586. free(a.dotted);
  587. if (a.atype == T_CNAME) { /* CNAME */
  588. DPRINTF("Got a CNAME in resolve_address()\n");
  589. i = decode_dotted(packet, a.rdoffset, temp, sizeof(temp));
  590. free(packet);
  591. if (i < 0)
  592. return -1;
  593. if (++nest > MAX_RECURSE)
  594. return -1;
  595. continue;
  596. } else if (a.atype == T_A) { /* ADDRESS */
  597. free(packet);
  598. break;
  599. } else {
  600. free(packet);
  601. return -1;
  602. }
  603. }
  604. if (in)
  605. memcpy(in, a.rdata, INADDRSZ); /* IPv4 T_A */
  606. return 0;
  607. }
  608. #endif
  609. #ifdef L_resolvemailbox
  610. int resolve_mailbox(const char *address, int nscount,
  611. char **nsip, struct in_addr *in)
  612. {
  613. struct resolv_answer a;
  614. unsigned char *packet;
  615. char temp[256];
  616. int nest = 0;
  617. int i;
  618. if (!address || !in)
  619. return -1;
  620. /* look up mail exchange */
  621. i = dns_lookup(address, T_MX, nscount, nsip, &packet, &a);
  622. strncpy(temp, address, sizeof(temp));
  623. if (i >= 0) {
  624. i = decode_dotted(packet, a.rdoffset+2, temp, sizeof(temp));
  625. free(packet);
  626. }
  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_mailbox()\n");
  634. i = decode_dotted(packet, a.rdoffset, temp, sizeof(temp));
  635. free(packet);
  636. if (i < 0)
  637. return i;
  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 */
  651. return 0;
  652. }
  653. #endif
  654. #ifdef L_opennameservers
  655. int nameservers;
  656. char * nameserver[MAX_SERVERS];
  657. int searchdomains;
  658. char * searchdomain[MAX_SEARCH];
  659. /*
  660. * we currently read formats not quite the same as that on normal
  661. * unix systems, we can have a list of nameservers after the keyword.
  662. */
  663. int open_nameservers()
  664. {
  665. FILE *fp;
  666. int i;
  667. #define RESOLV_ARGS 5
  668. char szBuffer[128], *p, *argv[RESOLV_ARGS];
  669. int argc;
  670. if (nameservers > 0)
  671. return 0;
  672. if ((fp = fopen("/etc/resolv.conf", "r")) ||
  673. (fp = fopen("/etc/config/resolv.conf", "r"))) {
  674. while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
  675. for (p = szBuffer; *p && isspace(*p); p++)
  676. /* skip white space */;
  677. if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */
  678. continue;
  679. argc = 0;
  680. while (*p && argc < RESOLV_ARGS) {
  681. argv[argc++] = p;
  682. while (*p && !isspace(*p) && *p != '\n')
  683. p++;
  684. while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */
  685. *p++ = '\0';
  686. }
  687. if (strcmp(argv[0], "nameserver") == 0) {
  688. for (i = 1; i < argc && nameservers < MAX_SERVERS; i++) {
  689. nameserver[nameservers++] = strdup(argv[i]);
  690. DPRINTF("adding nameserver %s\n", argv[i]);
  691. }
  692. }
  693. /* domain and search are mutually exclusive, the last one wins */
  694. if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) {
  695. while (searchdomains > 0) {
  696. free(searchdomain[--searchdomains]);
  697. searchdomain[searchdomains] = NULL;
  698. }
  699. for (i=1; i < argc && searchdomains < MAX_SEARCH; i++) {
  700. searchdomain[searchdomains++] = strdup(argv[i]);
  701. DPRINTF("adding search %s\n", argv[i]);
  702. }
  703. }
  704. }
  705. fclose(fp);
  706. } else {
  707. DPRINTF("failed to open %s\n", "resolv.conf");
  708. }
  709. DPRINTF("nameservers = %d\n", nameservers);
  710. return 0;
  711. }
  712. #endif
  713. #ifdef L_closenameservers
  714. void close_nameservers(void)
  715. {
  716. while (nameservers > 0) {
  717. free(nameserver[--nameservers]);
  718. nameserver[nameservers] = NULL;
  719. }
  720. while (searchdomains > 0) {
  721. free(searchdomain[--searchdomains]);
  722. searchdomain[searchdomains] = NULL;
  723. }
  724. }
  725. #endif
  726. #ifdef L_resolvename
  727. const char *resolve_name(const char *name, int mailbox)
  728. {
  729. struct in_addr in;
  730. int i;
  731. /* shortcut: is it a valid IP address to begin with? */
  732. if (inet_aton(name, &in))
  733. return name;
  734. open_nameservers();
  735. DPRINTF("looking up '%s', mailbox=%d, nameservers=%d\n",
  736. name, mailbox, nameservers);
  737. if (mailbox)
  738. i = resolve_mailbox(name, nameservers, nameserver, &in);
  739. else
  740. i = resolve_address(name, nameservers, nameserver, &in);
  741. if (i < 0)
  742. return 0;
  743. DPRINTF("success = '%s'\n", inet_ntoa(in));
  744. return inet_ntoa(in);
  745. }
  746. #endif
  747. #ifdef L_gethostbyname
  748. struct hostent *gethostbyname(const char *name)
  749. {
  750. static struct hostent h;
  751. static char namebuf[256];
  752. static struct in_addr in;
  753. static struct in_addr *addr_list[2];
  754. struct hostent *hp;
  755. unsigned char *packet;
  756. struct resolv_answer a;
  757. int i;
  758. int nest = 0;
  759. open_nameservers();
  760. if (!name)
  761. return 0;
  762. if ((hp = get_hosts_byname(name))) /* do /etc/hosts first */
  763. return(hp);
  764. memset(&h, 0, sizeof(h));
  765. addr_list[0] = &in;
  766. addr_list[1] = 0;
  767. strncpy(namebuf, name, sizeof(namebuf));
  768. /* First check if this is already an address */
  769. if (inet_aton(name, &in)) {
  770. h.h_name = namebuf;
  771. h.h_addrtype = AF_INET;
  772. h.h_length = sizeof(in);
  773. h.h_addr_list = (char **) addr_list;
  774. return &h;
  775. }
  776. for (;;) {
  777. i = dns_lookup(namebuf, 1, nameservers, nameserver, &packet, &a);
  778. if (i < 0)
  779. return 0;
  780. strncpy(namebuf, a.dotted, sizeof(namebuf));
  781. free(a.dotted);
  782. if (a.atype == T_CNAME) { /* CNAME */
  783. DPRINTF("Got a CNAME in gethostbyname()\n");
  784. i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf));
  785. free(packet);
  786. if (i < 0)
  787. return 0;
  788. if (++nest > MAX_RECURSE)
  789. return 0;
  790. continue;
  791. } else if (a.atype == T_A) { /* ADDRESS */
  792. memcpy(&in, a.rdata, sizeof(in));
  793. h.h_name = namebuf;
  794. h.h_addrtype = AF_INET;
  795. h.h_length = sizeof(in);
  796. h.h_addr_list = (char **) addr_list;
  797. free(packet);
  798. break;
  799. } else {
  800. free(packet);
  801. return 0;
  802. }
  803. }
  804. return &h;
  805. }
  806. #endif
  807. #ifdef L_gethostbyname2
  808. struct hostent *gethostbyname2(const char *name, int family)
  809. {
  810. #ifndef __UCLIBC_HAS_IPV6__
  811. return family == AF_INET ? gethostbyname(name) : (struct hostent*)0;
  812. #else /* __UCLIBC_HAS_IPV6__ */
  813. static struct hostent h;
  814. static char namebuf[256];
  815. static struct in6_addr in;
  816. static struct in6_addr *addr_list[2];
  817. struct hostent *hp;
  818. unsigned char *packet;
  819. struct resolv_answer a;
  820. int i;
  821. int nest = 0;
  822. if (family == AF_INET)
  823. return gethostbyname(name);
  824. if (family != AF_INET6)
  825. return NULL;
  826. open_nameservers();
  827. if (!name)
  828. return 0;
  829. if ((hp = get_hosts_byname(name))) /* do /etc/hosts first */
  830. return(hp);
  831. memset(&h, 0, sizeof(h));
  832. addr_list[0] = &in;
  833. addr_list[1] = 0;
  834. strncpy(namebuf, name, sizeof(namebuf));
  835. /* First check if this is already an address */
  836. if (inet_pton(AF_INET6, name, &in)) {
  837. h.h_name = namebuf;
  838. h.h_addrtype = AF_INET6;
  839. h.h_length = sizeof(in);
  840. h.h_addr_list = (char **) addr_list;
  841. return &h;
  842. }
  843. for (;;) {
  844. i = dns_lookup(namebuf, T_AAAA, nameservers, nameserver, &packet, &a);
  845. if (i < 0)
  846. return 0;
  847. strncpy(namebuf, a.dotted, sizeof(namebuf));
  848. free(a.dotted);
  849. if (a.atype == T_CNAME) { /* CNAME */
  850. DPRINTF("Got a CNAME in gethostbyname()\n");
  851. i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf));
  852. free(packet);
  853. if (i < 0)
  854. return 0;
  855. if (++nest > MAX_RECURSE)
  856. return 0;
  857. continue;
  858. } else if (a.atype == T_AAAA) { /* ADDRESS */
  859. memcpy(&in, a.rdata, sizeof(in));
  860. h.h_name = namebuf;
  861. h.h_addrtype = AF_INET6;
  862. h.h_length = sizeof(in);
  863. h.h_addr_list = (char **) addr_list;
  864. free(packet);
  865. break;
  866. } else {
  867. free(packet);
  868. return 0;
  869. }
  870. }
  871. return &h;
  872. #endif /* __UCLIBC_HAS_IPV6__ */
  873. }
  874. #endif
  875. #ifdef L_getnetbyname
  876. struct netent * getnetbyname(const char * name)
  877. {
  878. return NULL;
  879. }
  880. #endif
  881. #ifdef L_res_init
  882. int res_init()
  883. {
  884. return(0);
  885. }
  886. #endif
  887. #ifdef L_res_query
  888. #ifndef MIN
  889. #define MIN(x, y) ((x) < (y) ? (x) : (y))
  890. #endif
  891. int res_query(const char *dname, int class, int type,
  892. unsigned char *answer, int anslen)
  893. {
  894. unsigned char * packet = 0;
  895. struct resolv_answer a;
  896. int i;
  897. open_nameservers();
  898. if (!dname || class != 1 /* CLASS_IN */)
  899. return(-1);
  900. memset((char *) &a, '\0', sizeof(a));
  901. i = dns_lookup(dname, type, nameservers, nameserver, &packet, &a);
  902. if (i < 0)
  903. return(-1);
  904. free(a.dotted);
  905. if (a.atype == type) { /* CNAME*/
  906. if (anslen && answer)
  907. memcpy(answer, a.rdata, MIN(anslen, a.rdlength));
  908. if (packet)
  909. free(packet);
  910. return(MIN(anslen, a.rdlength));
  911. }
  912. if (packet)
  913. free(packet);
  914. return 0;
  915. }
  916. #endif
  917. #ifdef L_gethostbyaddr
  918. struct hostent *gethostbyaddr(const char *addr, int len, int type)
  919. {
  920. static struct hostent h;
  921. static char namebuf[256];
  922. static struct in_addr in;
  923. static struct in_addr *addr_list[2];
  924. struct hostent *hp;
  925. unsigned char *packet;
  926. struct resolv_answer a;
  927. int i;
  928. int nest = 0;
  929. if (!addr || (len != sizeof(in)) || (type != AF_INET))
  930. return 0;
  931. if ((hp = get_hosts_byaddr(addr, len, type))) /* do /etc/hosts first */
  932. return(hp);
  933. memcpy(&in.s_addr, addr, len);
  934. open_nameservers();
  935. memset(&h, 0, sizeof(h));
  936. addr_list[0] = &in;
  937. addr_list[1] = 0;
  938. sprintf(namebuf, "%d.%d.%d.%d.in-addr.arpa",
  939. (in.s_addr >> 24) & 0xff,
  940. (in.s_addr >> 16) & 0xff,
  941. (in.s_addr >> 8) & 0xff,
  942. (in.s_addr >> 0) & 0xff);
  943. for (;;) {
  944. i = dns_lookup(namebuf, T_PTR, nameservers, nameserver, &packet, &a);
  945. if (i < 0)
  946. return 0;
  947. strncpy(namebuf, a.dotted, sizeof(namebuf));
  948. free(a.dotted);
  949. if (a.atype == T_CNAME) { /* CNAME */
  950. DPRINTF("Got a CNAME in gethostbyaddr()\n");
  951. i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf));
  952. free(packet);
  953. if (i < 0)
  954. return 0;
  955. if (++nest > MAX_RECURSE)
  956. return 0;
  957. continue;
  958. } else if (a.atype == T_PTR) { /* ADDRESS */
  959. i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf));
  960. free(packet);
  961. h.h_name = namebuf;
  962. h.h_addrtype = AF_INET;
  963. h.h_length = sizeof(in);
  964. h.h_addr_list = (char **) addr_list;
  965. break;
  966. } else {
  967. free(packet);
  968. return 0;
  969. }
  970. }
  971. return &h;
  972. }
  973. #endif
  974. #ifdef L_read_etc_hosts
  975. struct hostent * read_etc_hosts(const char * name, int ip)
  976. {
  977. static struct hostent h;
  978. static struct in_addr in;
  979. static struct in_addr *addr_list[2];
  980. #ifdef __UCLIBC_HAS_IPV6__
  981. static struct in6_addr in6;
  982. static struct in6_addr *addr_list6[2];
  983. #endif /* __UCLIBC_HAS_IPV6__ */
  984. static char line[80];
  985. FILE *fp;
  986. char *cp;
  987. #define MAX_ALIAS 5
  988. char *alias[MAX_ALIAS];
  989. int aliases, i;
  990. if ((fp = fopen("/etc/hosts", "r")) == NULL &&
  991. (fp = fopen("/etc/config/hosts", "r")) == NULL)
  992. return((struct hostent *) NULL);
  993. while (fgets(line, sizeof(line), fp)) {
  994. if ((cp = strchr(line, '#')))
  995. *cp = '\0';
  996. aliases = 0;
  997. cp = line;
  998. while (*cp) {
  999. while (*cp && isspace(*cp))
  1000. *cp++ = '\0';
  1001. if (!*cp)
  1002. continue;
  1003. if (aliases < MAX_ALIAS)
  1004. alias[aliases++] = cp;
  1005. while (*cp && !isspace(*cp))
  1006. cp++;
  1007. }
  1008. if (aliases < 2)
  1009. continue; /* syntax error really */
  1010. if (ip) {
  1011. if (strcmp(name, alias[0]) != 0)
  1012. continue;
  1013. } else {
  1014. for (i = 1; i < aliases; i++)
  1015. if (strcasecmp(name, alias[i]) == 0)
  1016. break;
  1017. if (i >= aliases)
  1018. continue;
  1019. }
  1020. #ifndef __UCLIBC_HAS_IPV6__
  1021. if (inet_aton(alias[0], &in) == 0)
  1022. break; /* bad ip address */
  1023. #else /* __UCLIBC_HAS_IPV6__ */
  1024. if (inet_aton(alias[0], &in) == 0) {
  1025. if (inet_pton(AF_INET6, alias[0], &in6) == 0) {
  1026. addr_list6[0] = &in6;
  1027. addr_list6[1] = 0;
  1028. h.h_name = alias[1];
  1029. h.h_addrtype = AF_INET6;
  1030. h.h_length = sizeof(in6);
  1031. h.h_addr_list = (char**) addr_list6;
  1032. fclose(fp);
  1033. return(&h);
  1034. } else
  1035. break; /* bad ip address */
  1036. }
  1037. #endif /* __UCLIBC_HAS_IPV6__ */
  1038. addr_list[0] = &in;
  1039. addr_list[1] = 0;
  1040. h.h_name = alias[1];
  1041. h.h_addrtype = AF_INET;
  1042. h.h_length = sizeof(in);
  1043. h.h_addr_list = (char**) addr_list;
  1044. fclose(fp);
  1045. return(&h);
  1046. }
  1047. fclose(fp);
  1048. return((struct hostent *) NULL);
  1049. }
  1050. #endif
  1051. #ifdef L_get_hosts_byname
  1052. struct hostent * get_hosts_byname(const char * name)
  1053. {
  1054. return(read_etc_hosts(name, 0));
  1055. }
  1056. #endif
  1057. #ifdef L_get_hosts_byaddr
  1058. struct hostent * get_hosts_byaddr(const char * addr, int len, int type)
  1059. {
  1060. char ipaddr[20];
  1061. if (type != AF_INET || len != sizeof(struct in_addr))
  1062. return((struct hostent *) NULL);
  1063. strcpy(ipaddr, inet_ntoa(* (struct in_addr *) addr));
  1064. return(read_etc_hosts(ipaddr, 1));
  1065. }
  1066. #endif