1 /*
2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * Copyright (c) 1985, 1988 Regents of the University of California.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms are permitted
11 * provided that this notice is preserved and that due credit is given
12 * to the University of California at Berkeley. The name of the University
13 * may not be used to endorse or promote products derived from this
14 * software without specific prior written permission. This software
15 * is provided ``as is'' without express or implied warranty.
16 *
17 */
18
19 #include <sys/param.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <ctype.h>
23 #include <netdb.h>
24 #include <stdio.h>
25 #include <errno.h>
26 #include <arpa/inet.h>
27 #include <arpa/nameser.h>
28 #include <resolv.h>
29 #include <syslog.h>
30
31 /*
32 * When the name service switch calls libresolv, it doesn't want fallback
33 * to /etc/hosts, so we provide a method to turn it off.
34 */
35 static int no_hosts_fallback = 0;
36
37 void
38 __res_set_no_hosts_fallback(void) {
39 no_hosts_fallback = 1;
40 }
41
42 static int
43 __res_no_hosts_fallback(void) {
44 return(no_hosts_fallback);
45 }
46
47 static char *h_addr_ptrs[MAXADDRS + 1];
48
49 static struct hostent host;
86 register u_char *cp;
87 register int n;
88 u_char *eom;
89 char *bp, **ap;
90 int type, class, buflen, ancount, qdcount;
91 int haveanswer, getclass = C_ANY;
92 char **hap;
93
94 eom = answer->buf + anslen;
95 /*
96 * find first satisfactory answer
97 */
98 hp = &answer->hdr;
99 ancount = ntohs(hp->ancount);
100 qdcount = ntohs(hp->qdcount);
101 bp = hostbuf;
102 buflen = sizeof (hostbuf);
103 cp = answer->buf + sizeof (HEADER);
104 if (qdcount) {
105 if (iquery) {
106 if ((n = dn_expand((char *)answer->buf, eom,
107 cp, bp, buflen)) < 0) {
108 h_errno = NO_RECOVERY;
109 return ((struct hostent *) NULL);
110 }
111 cp += n + QFIXEDSZ;
112 host.h_name = bp;
113 n = strlen(bp) + 1;
114 bp += n;
115 buflen -= n;
116 } else
117 cp += dn_skipname(cp, eom) + QFIXEDSZ;
118 while (--qdcount > 0)
119 cp += dn_skipname(cp, eom) + QFIXEDSZ;
120 } else if (iquery) {
121 if (hp->aa)
122 h_errno = HOST_NOT_FOUND;
123 else
124 h_errno = TRY_AGAIN;
125 return ((struct hostent *) NULL);
126 }
127 ap = host_aliases;
128 host.h_aliases = host_aliases;
129 hap = h_addr_ptrs;
130 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
131 host.h_addr_list = h_addr_ptrs;
132 #endif
133 haveanswer = 0;
134 while (--ancount >= 0 && cp < eom && haveanswer < MAXADDRS) {
135 if ((n = dn_expand((char *)answer->buf, eom,
136 cp, bp, buflen)) < 0)
137 break;
138 cp += n;
139 type = _getshort(cp);
140 cp += sizeof (u_short);
141 class = _getshort(cp);
142 cp += sizeof (u_short) + sizeof (u_long);
143 n = _getshort(cp);
144 cp += sizeof (u_short);
145 if (type == T_CNAME) {
146 cp += n;
147 if (ap >= &host_aliases[MAXALIASES-1])
148 continue;
149 *ap++ = bp;
150 n = strlen(bp) + 1;
151 bp += n;
152 buflen -= n;
153 continue;
154 }
155 if (iquery && type == T_PTR) {
156 if ((n = dn_expand((char *)answer->buf, eom,
157 cp, bp, buflen)) < 0) {
158 cp += n;
159 continue;
160 }
161 cp += n;
162 host.h_name = bp;
163 return (&host);
164 }
165 if (iquery || type != T_A) {
166 #ifdef DEBUG
167 if (_res.options & RES_DEBUG)
168 printf("unexpected answer type %d, size %d\n",
169 type, n);
170 #endif
171 cp += n;
172 continue;
173 }
174 if (haveanswer) {
175 if (n != host.h_length) {
176 cp += n;
177 continue;
214 *hap = NULL;
215 #else
216 host.h_addr = h_addr_ptrs[0];
217 #endif
218 return (&host);
219 } else {
220 h_errno = TRY_AGAIN;
221 return ((struct hostent *) NULL);
222 }
223 }
224
225 static struct hostent *_gethtbyname();
226
227 struct hostent *
228 res_gethostbyname(name)
229 char *name;
230 {
231 querybuf buf;
232 register char *cp;
233 int n;
234 struct hostent *hp, *gethostdomain();
235
236 /*
237 * disallow names consisting only of digits/dots, unless
238 * they end in a dot.
239 */
240 if (isdigit(name[0]))
241 for (cp = name; /*EMPTY*/; ++cp) {
242 if (!*cp) {
243 if (*--cp == '.')
244 break;
245 h_errno = HOST_NOT_FOUND;
246 return ((struct hostent *) NULL);
247 }
248 if (!isdigit(*cp) && *cp != '.')
249 break;
250 }
251
252 if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof (buf))) < 0) {
253 #ifdef DEBUG
254 if (_res.options & RES_DEBUG)
264
265 static struct hostent *_gethtbyaddr();
266
267 static struct hostent *
268 _getrhbyaddr(addr, len, type)
269 char *addr;
270 int len, type;
271 {
272 int n;
273 querybuf buf;
274 register struct hostent *hp;
275 char qbuf[MAXDNAME];
276
277 if (type != AF_INET)
278 return ((struct hostent *) NULL);
279 (void) sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa",
280 ((unsigned)addr[3] & 0xff),
281 ((unsigned)addr[2] & 0xff),
282 ((unsigned)addr[1] & 0xff),
283 ((unsigned)addr[0] & 0xff));
284 n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof (buf));
285 if (n < 0) {
286 #ifdef DEBUG
287 if (_res.options & RES_DEBUG)
288 printf("res_query failed\n");
289 #endif
290 if (errno == ECONNREFUSED)
291 return (_gethtbyaddr(addr, len, type));
292 return ((struct hostent *) NULL);
293 }
294 hp = getanswer(&buf, n, 1);
295 if (hp == NULL)
296 return ((struct hostent *) NULL);
297 hp->h_addrtype = type;
298 hp->h_length = len;
299 h_addr_ptrs[0] = (char *)&host_addr;
300 h_addr_ptrs[1] = (char *)0;
301 host_addr = *(struct in_addr *)addr;
302 return (hp);
303 }
304
|
1 /*
2 * Copyright 2015 Gary Mills
3 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
4 * Use is subject to license terms.
5 */
6
7 /*
8 * Copyright (c) 1985, 1988 Regents of the University of California.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms are permitted
12 * provided that this notice is preserved and that due credit is given
13 * to the University of California at Berkeley. The name of the University
14 * may not be used to endorse or promote products derived from this
15 * software without specific prior written permission. This software
16 * is provided ``as is'' without express or implied warranty.
17 *
18 */
19
20 #include <sys/param.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <ctype.h>
24 #include <netdb.h>
25 #include <stdio.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <arpa/inet.h>
29 #include <arpa/nameser.h>
30 #include <resolv.h>
31 #include <syslog.h>
32 #include "crossl.h"
33
34 /*
35 * When the name service switch calls libresolv, it doesn't want fallback
36 * to /etc/hosts, so we provide a method to turn it off.
37 */
38 static int no_hosts_fallback = 0;
39
40 void
41 __res_set_no_hosts_fallback(void) {
42 no_hosts_fallback = 1;
43 }
44
45 static int
46 __res_no_hosts_fallback(void) {
47 return(no_hosts_fallback);
48 }
49
50 static char *h_addr_ptrs[MAXADDRS + 1];
51
52 static struct hostent host;
89 register u_char *cp;
90 register int n;
91 u_char *eom;
92 char *bp, **ap;
93 int type, class, buflen, ancount, qdcount;
94 int haveanswer, getclass = C_ANY;
95 char **hap;
96
97 eom = answer->buf + anslen;
98 /*
99 * find first satisfactory answer
100 */
101 hp = &answer->hdr;
102 ancount = ntohs(hp->ancount);
103 qdcount = ntohs(hp->qdcount);
104 bp = hostbuf;
105 buflen = sizeof (hostbuf);
106 cp = answer->buf + sizeof (HEADER);
107 if (qdcount) {
108 if (iquery) {
109 if ((n = dn_expand(answer->buf, eom,
110 cp, (u_char *)bp, buflen)) < 0) {
111 h_errno = NO_RECOVERY;
112 return ((struct hostent *) NULL);
113 }
114 cp += n + QFIXEDSZ;
115 host.h_name = bp;
116 n = strlen(bp) + 1;
117 bp += n;
118 buflen -= n;
119 } else
120 cp += dn_skipname(cp, eom) + QFIXEDSZ;
121 while (--qdcount > 0)
122 cp += dn_skipname(cp, eom) + QFIXEDSZ;
123 } else if (iquery) {
124 if (hp->aa)
125 h_errno = HOST_NOT_FOUND;
126 else
127 h_errno = TRY_AGAIN;
128 return ((struct hostent *) NULL);
129 }
130 ap = host_aliases;
131 host.h_aliases = host_aliases;
132 hap = h_addr_ptrs;
133 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
134 host.h_addr_list = h_addr_ptrs;
135 #endif
136 haveanswer = 0;
137 while (--ancount >= 0 && cp < eom && haveanswer < MAXADDRS) {
138 if ((n = dn_expand(answer->buf, eom,
139 cp, (u_char *)bp, buflen)) < 0)
140 break;
141 cp += n;
142 type = _getshort(cp);
143 cp += sizeof (u_short);
144 class = _getshort(cp);
145 cp += sizeof (u_short) + sizeof (u_long);
146 n = _getshort(cp);
147 cp += sizeof (u_short);
148 if (type == T_CNAME) {
149 cp += n;
150 if (ap >= &host_aliases[MAXALIASES-1])
151 continue;
152 *ap++ = bp;
153 n = strlen(bp) + 1;
154 bp += n;
155 buflen -= n;
156 continue;
157 }
158 if (iquery && type == T_PTR) {
159 if ((n = dn_expand(answer->buf, eom,
160 cp, (u_char *)bp, buflen)) < 0) {
161 cp += n;
162 continue;
163 }
164 cp += n;
165 host.h_name = bp;
166 return (&host);
167 }
168 if (iquery || type != T_A) {
169 #ifdef DEBUG
170 if (_res.options & RES_DEBUG)
171 printf("unexpected answer type %d, size %d\n",
172 type, n);
173 #endif
174 cp += n;
175 continue;
176 }
177 if (haveanswer) {
178 if (n != host.h_length) {
179 cp += n;
180 continue;
217 *hap = NULL;
218 #else
219 host.h_addr = h_addr_ptrs[0];
220 #endif
221 return (&host);
222 } else {
223 h_errno = TRY_AGAIN;
224 return ((struct hostent *) NULL);
225 }
226 }
227
228 static struct hostent *_gethtbyname();
229
230 struct hostent *
231 res_gethostbyname(name)
232 char *name;
233 {
234 querybuf buf;
235 register char *cp;
236 int n;
237
238 /*
239 * disallow names consisting only of digits/dots, unless
240 * they end in a dot.
241 */
242 if (isdigit(name[0]))
243 for (cp = name; /*EMPTY*/; ++cp) {
244 if (!*cp) {
245 if (*--cp == '.')
246 break;
247 h_errno = HOST_NOT_FOUND;
248 return ((struct hostent *) NULL);
249 }
250 if (!isdigit(*cp) && *cp != '.')
251 break;
252 }
253
254 if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof (buf))) < 0) {
255 #ifdef DEBUG
256 if (_res.options & RES_DEBUG)
266
267 static struct hostent *_gethtbyaddr();
268
269 static struct hostent *
270 _getrhbyaddr(addr, len, type)
271 char *addr;
272 int len, type;
273 {
274 int n;
275 querybuf buf;
276 register struct hostent *hp;
277 char qbuf[MAXDNAME];
278
279 if (type != AF_INET)
280 return ((struct hostent *) NULL);
281 (void) sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa",
282 ((unsigned)addr[3] & 0xff),
283 ((unsigned)addr[2] & 0xff),
284 ((unsigned)addr[1] & 0xff),
285 ((unsigned)addr[0] & 0xff));
286 n = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof (buf));
287 if (n < 0) {
288 #ifdef DEBUG
289 if (_res.options & RES_DEBUG)
290 printf("res_query failed\n");
291 #endif
292 if (errno == ECONNREFUSED)
293 return (_gethtbyaddr(addr, len, type));
294 return ((struct hostent *) NULL);
295 }
296 hp = getanswer(&buf, n, 1);
297 if (hp == NULL)
298 return ((struct hostent *) NULL);
299 hp->h_addrtype = type;
300 hp->h_length = len;
301 h_addr_ptrs[0] = (char *)&host_addr;
302 h_addr_ptrs[1] = (char *)0;
303 host_addr = *(struct in_addr *)addr;
304 return (hp);
305 }
306
|