1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52: #if defined(LIBC_SCCS) && !defined(lint)
53: static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
54: #endif
55:
56: #include <sys/types.h>
57: #include <sys/param.h>
58: #include <sys/socket.h>
59: #include <netinet/in.h>
60: #include <arpa/inet.h>
61: #include <arpa/nameser.h>
62:
63: #include <stdio.h>
64: #include <netdb.h>
65: #include <resolv.h>
66: #include <ctype.h>
67: #include <errno.h>
68: #include <syslog.h>
69:
70: #define RESOLVSORT
71:
72: #ifndef LOG_AUTH
73: # define LOG_AUTH 0
74: #endif
75:
76: #define MULTI_PTRS_ARE_ALIASES 1
77:
78: #if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
79: # include <stdlib.h>
80: # include <string.h>
81: #else
82: # include "../conf/portability.h"
83: #endif
84:
85: #if defined(USE_OPTIONS_H)
86: # include <../conf/options.h>
87: #endif
88:
89: #ifdef SPRINTF_CHAR
90: # define SPRINTF(x) strlen(sprintfx)
91: #else
92: # define SPRINTF(x) ((size_t)sprintf x)
93: #endif
94:
95: #define MAXALIASES 35
96: #define MAXADDRS 35
97:
98: static const char AskedForGot[] =
99: "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
100:
101: static char *h_addr_ptrs[MAXADDRS + 1];
102:
103: static struct hostent host;
104: static char *host_aliases[MAXALIASES];
105: static char hostbuf[8*1024];
106: static u_char host_addr[16];
107: static FILE *hostf = NULL;
108: static int stayopen = 0;
109:
110: static void map_v4v6_address (const char *src, char *dst) __THROW;
111: static void map_v4v6_hostent (struct hostent *hp, char **bp, int *len) __THROW;
112:
113: #ifdef RESOLVSORT
114: extern void addrsort (char **, int) __THROW;
115: #endif
116:
117: #if PACKETSZ > 65536
118: #define MAXPACKET PACKETSZ
119: #else
120: #define MAXPACKET 65536
121: #endif
122:
123:
124: #ifdef MAXHOSTNAMELEN
125: # undef MAXHOSTNAMELEN
126: #endif
127: #define MAXHOSTNAMELEN 256
128:
129: typedef union {
130: HEADER hdr;
131: u_char buf[MAXPACKET];
132: } querybuf;
133:
134: typedef union {
135: int32_t al;
136: char ac;
137: } align;
138:
139: #ifndef h_errno
140: extern int h_errno;
141: #endif
142:
143: #ifdef DEBUG
144: static void
145: Dprintf(msg, num)
146: char *msg;
147: int num;
148: {
149: if (_res.options & RES_DEBUG) {
150: int save = errno;
151:
152: printf(msg, num);
153: __set_errno (save);
154: }
155: }
156: #else
157: # define Dprintf(msg, num)
158: #endif
159:
160: #define BOUNDED_INCR(x) \
161: do { \
162: cp += x; \
163: if (cp > eom) { \
164: __set_h_errno (NO_RECOVERY); \
165: return (NULL); \
166: } \
167: } while (0)
168:
169: #define BOUNDS_CHECK(ptr, count) \
170: do { \
171: if ((ptr) + (count) > eom) { \
172: __set_h_errno (NO_RECOVERY); \
173: return (NULL); \
174: } \
175: } while (0)
176:
177:
178: static struct hostent *
179: getanswer (const querybuf *answer, int anslen, const char *qname, int qtype)
180: {
181: register const HEADER *hp;
182: register const u_char *cp;
183: register int n;
184: const u_char *eom, *erdata;
185: char *bp, **ap, **hap;
186: int type, class, buflen, ancount, qdcount;
187: int haveanswer, had_error;
188: int toobig = 0;
189: char tbuf[MAXDNAME];
190: const char *tname;
191: int (*name_ok) (const char *);
192:
193: tname = qname;
194: host.h_name = NULL;
195: eom = answer->buf + anslen;
196: switch (qtype) {
197: case T_A:
198: case T_AAAA:
199: name_ok = res_hnok;
200: break;
201: case T_PTR:
202: name_ok = res_dnok;
203: break;
204: default:
205: return (NULL);
206: }
207:
208:
209:
210: hp = &answer->hdr;
211: ancount = ntohs(hp->ancount);
212: qdcount = ntohs(hp->qdcount);
213: bp = hostbuf;
214: buflen = sizeof hostbuf;
215: cp = answer->buf;
216: BOUNDED_INCR(HFIXEDSZ);
217: if (qdcount != 1) {
218: __set_h_errno (NO_RECOVERY);
219: return (NULL);
220: }
221: n = dn_expand(answer->buf, eom, cp, bp, buflen);
222: if ((n < 0) || !(*name_ok)(bp)) {
223: __set_h_errno (NO_RECOVERY);
224: return (NULL);
225: }
226: BOUNDED_INCR(n + QFIXEDSZ);
227: if (qtype == T_A || qtype == T_AAAA) {
228:
229:
230:
231:
232: n = strlen(bp) + 1;
233: if (n >= MAXHOSTNAMELEN) {
234: __set_h_errno (NO_RECOVERY);
235: return (NULL);
236: }
237: host.h_name = bp;
238: bp += n;
239: buflen -= n;
240:
241: qname = host.h_name;
242: }
243: ap = host_aliases;
244: *ap = NULL;
245: host.h_aliases = host_aliases;
246: hap = h_addr_ptrs;
247: *hap = NULL;
248: host.h_addr_list = h_addr_ptrs;
249: haveanswer = 0;
250: had_error = 0;
251: while (ancount-- > 0 && cp < eom && !had_error) {
252: n = dn_expand(answer->buf, eom, cp, bp, buflen);
253: if ((n < 0) || !(*name_ok)(bp)) {
254: had_error++;
255: continue;
256: }
257: cp += n;
258: BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
259: type = ns_get16(cp);
260: cp += INT16SZ;
261: class = ns_get16(cp);
262: cp += INT16SZ + INT32SZ;
263: n = ns_get16(cp);
264: cp += INT16SZ;
265: BOUNDS_CHECK(cp, n);
266: erdata = cp + n;
267: if (class != C_IN) {
268:
269: cp += n;
270: continue;
271: }
272: if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
273: if (ap >= &host_aliases[MAXALIASES-1])
274: continue;
275: n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
276: if ((n < 0) || !(*name_ok)(tbuf)) {
277: had_error++;
278: continue;
279: }
280: cp += n;
281: if (cp != erdata) {
282: __set_h_errno (NO_RECOVERY);
283: return (NULL);
284: }
285:
286: *ap++ = bp;
287: n = strlen(bp) + 1;
288: if (n >= MAXHOSTNAMELEN) {
289: had_error++;
290: continue;
291: }
292: bp += n;
293: buflen -= n;
294:
295: n = strlen(tbuf) + 1;
296: if (n > buflen || n >= MAXHOSTNAMELEN) {
297: had_error++;
298: continue;
299: }
300: strcpy(bp, tbuf);
301: host.h_name = bp;
302: bp += n;
303: buflen -= n;
304: continue;
305: }
306: if (qtype == T_PTR && type == T_CNAME) {
307: n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
308: if (n < 0 || !res_dnok(tbuf)) {
309: had_error++;
310: continue;
311: }
312: cp += n;
313: if (cp != erdata) {
314: __set_h_errno (NO_RECOVERY);
315: return (NULL);
316: }
317:
318: n = strlen(tbuf) + 1;
319: if (n > buflen || n >= MAXHOSTNAMELEN) {
320: had_error++;
321: continue;
322: }
323: strcpy(bp, tbuf);
324: tname = bp;
325: bp += n;
326: buflen -= n;
327: continue;
328: }
329: if ((type == T_SIG) || (type == T_KEY) || (type == T_NXT)) {
330:
331:
332:
333:
334: syslog(LOG_DEBUG|LOG_AUTH,
335: "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
336: qname, p_class(C_IN), p_type(qtype),
337: p_type(type));
338: cp += n;
339: continue;
340: }
341: if (type != qtype) {
342: syslog(LOG_NOTICE|LOG_AUTH,
343: "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
344: qname, p_class(C_IN), p_type(qtype),
345: p_type(type));
346: cp += n;
347: continue;
348: }
349: switch (type) {
350: case T_PTR:
351: if (strcasecmp(tname, bp) != 0) {
352: syslog(LOG_NOTICE|LOG_AUTH,
353: AskedForGot, qname, bp);
354: cp += n;
355: continue;
356: }
357: n = dn_expand(answer->buf, eom, cp, bp, buflen);
358: if ((n < 0) || !res_hnok(bp)) {
359: had_error++;
360: break;
361: }
362: #if MULTI_PTRS_ARE_ALIASES
363: cp += n;
364: if (cp != erdata) {
365: __set_h_errno (NO_RECOVERY);
366: return (NULL);
367: }
368: if (!haveanswer)
369: host.h_name = bp;
370: else if (ap < &host_aliases[MAXALIASES-1])
371: *ap++ = bp;
372: else
373: n = -1;
374: if (n != -1) {
375: n = strlen(bp) + 1;
376: if (n >= MAXHOSTNAMELEN) {
377: had_error++;
378: break;
379: }
380: bp += n;
381: buflen -= n;
382: }
383: break;
384: #else
385: host.h_name = bp;
386: if (_res.options & RES_USE_INET6) {
387: n = strlen(bp) + 1;
388: if (n >= MAXHOSTNAMELEN) {
389: had_error++;
390: break;
391: }
392: bp += n;
393: buflen -= n;
394: map_v4v6_hostent(&host, &bp, &buflen);
395: }
396: __set_h_errno (NETDB_SUCCESS);
397: return (&host);
398: #endif
399: case T_A:
400: case T_AAAA:
401: if (strcasecmp(host.h_name, bp) != 0) {
402: syslog(LOG_NOTICE|LOG_AUTH,
403: AskedForGot, host.h_name, bp);
404: cp += n;
405: continue;
406: }
407: if (n != host.h_length) {
408: cp += n;
409: continue;
410: }
411: if (!haveanswer) {
412: register int nn;
413:
414: host.h_name = bp;
415: nn = strlen(bp) + 1;
416: bp += nn;
417: buflen -= nn;
418: }
419:
420:
421:
422: buflen -= sizeof(align) - ((u_long)bp % sizeof(align));
423:
424: bp += sizeof(align) - ((u_long)bp % sizeof(align));
425:
426: if (bp + n >= &hostbuf[sizeof hostbuf]) {
427: Dprintf("size (%d) too big\n", n);
428: had_error++;
429: continue;
430: }
431: if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
432: if (!toobig++) {
433: Dprintf("Too many addresses (%d)\n",
434: MAXADDRS);
435: }
436: cp += n;
437: continue;
438: }
439: memmove(*hap++ = bp, cp, n);
440: bp += n;
441: buflen -= n;
442: cp += n;
443: if (cp != erdata) {
444: __set_h_errno (NO_RECOVERY);
445: return (NULL);
446: }
447: break;
448: default:
449: abort();
450: }
451: if (!had_error)
452: haveanswer++;
453: }
454: if (haveanswer) {
455: *ap = NULL;
456: *hap = NULL;
457: # if defined(RESOLVSORT)
458:
459:
460:
461:
462:
463: if (_res.nsort && haveanswer > 1 && qtype == T_A)
464: addrsort(h_addr_ptrs, haveanswer);
465: # endif
466: if (!host.h_name) {
467: n = strlen(qname) + 1;
468: if (n > buflen || n >= MAXHOSTNAMELEN)
469: goto no_recovery;
470: strcpy(bp, qname);
471: host.h_name = bp;
472: bp += n;
473: buflen -= n;
474: }
475: if (_res.options & RES_USE_INET6)
476: map_v4v6_hostent(&host, &bp, &buflen);
477: __set_h_errno (NETDB_SUCCESS);
478: return (&host);
479: }
480: no_recovery:
481: __set_h_errno (NO_RECOVERY);
482: return (NULL);
483: }
484:
485: extern struct hostent *gethostbyname2(const char *name, int af);
486: libresolv_hidden_proto (gethostbyname2)
487:
488: struct hostent *
489: gethostbyname(name)
490: const char *name;
491: {
492: struct hostent *hp;
493:
494: if (__res_maybe_init (&_res, 0) == -1) {
495: __set_h_errno (NETDB_INTERNAL);
496: return (NULL);
497: }
498: if (_res.options & RES_USE_INET6) {
499: hp = gethostbyname2(name, AF_INET6);
500: if (hp)
501: return (hp);
502: }
503: return (gethostbyname2(name, AF_INET));
504: }
505:
506: struct hostent *
507: gethostbyname2(name, af)
508: const char *name;
509: int af;
510: {
511: union
512: {
513: querybuf *buf;
514: u_char *ptr;
515: } buf;
516: querybuf *origbuf;
517: register const char *cp;
518: char *bp;
519: int n, size, type, len;
520: struct hostent *ret;
521:
522: if (__res_maybe_init (&_res, 0) == -1) {
523: __set_h_errno (NETDB_INTERNAL);
524: return (NULL);
525: }
526:
527: switch (af) {
528: case AF_INET:
529: size = INADDRSZ;
530: type = T_A;
531: break;
532: case AF_INET6:
533: size = IN6ADDRSZ;
534: type = T_AAAA;
535: break;
536: default:
537: __set_h_errno (NETDB_INTERNAL);
538: __set_errno (EAFNOSUPPORT);
539: return (NULL);
540: }
541:
542: host.h_addrtype = af;
543: host.h_length = size;
544: