summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/gethostnamadr.c
diff options
context:
space:
mode:
authorderaadt <>1995-10-18 08:42:23 +0000
committerderaadt <>1995-10-18 08:42:23 +0000
commit0527d29da443886d92e9a418180c5b25a5f8d270 (patch)
tree86b3a64928451a669cefa27900e5884036b4e349 /src/lib/libc/net/gethostnamadr.c
downloadopenbsd-0527d29da443886d92e9a418180c5b25a5f8d270.tar.gz
openbsd-0527d29da443886d92e9a418180c5b25a5f8d270.tar.bz2
openbsd-0527d29da443886d92e9a418180c5b25a5f8d270.zip
initial import of NetBSD tree
Diffstat (limited to 'src/lib/libc/net/gethostnamadr.c')
-rw-r--r--src/lib/libc/net/gethostnamadr.c654
1 files changed, 654 insertions, 0 deletions
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c
new file mode 100644
index 0000000000..ec3f14a900
--- /dev/null
+++ b/src/lib/libc/net/gethostnamadr.c
@@ -0,0 +1,654 @@
1/* $NetBSD: gethostnamadr.c,v 1.13 1995/05/21 16:21:14 mycroft Exp $ */
2
3/*-
4 * Copyright (c) 1985, 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 * -
35 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
36 *
37 * Permission to use, copy, modify, and distribute this software for any
38 * purpose with or without fee is hereby granted, provided that the above
39 * copyright notice and this permission notice appear in all copies, and that
40 * the name of Digital Equipment Corporation not be used in advertising or
41 * publicity pertaining to distribution of the document or software without
42 * specific, written prior permission.
43 *
44 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
45 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
46 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
47 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
48 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
49 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
50 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
51 * SOFTWARE.
52 * -
53 * --Copyright--
54 */
55
56#if defined(LIBC_SCCS) && !defined(lint)
57#if 0
58static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: gethnamaddr.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
60#else
61static char rcsid[] = "$NetBSD: gethostnamadr.c,v 1.13 1995/05/21 16:21:14 mycroft Exp $";
62#endif
63#endif /* LIBC_SCCS and not lint */
64
65#include <sys/param.h>
66#include <sys/socket.h>
67#include <netinet/in.h>
68#include <arpa/inet.h>
69#include <arpa/nameser.h>
70#include <netdb.h>
71#include <resolv.h>
72#include <stdio.h>
73#include <ctype.h>
74#include <errno.h>
75#include <string.h>
76#ifdef YP
77#include <rpc/rpc.h>
78#include <rpcsvc/yp_prot.h>
79#include <rpcsvc/ypclnt.h>
80#endif
81
82#define MAXALIASES 35
83#define MAXADDRS 35
84
85static char *h_addr_ptrs[MAXADDRS + 1];
86
87#ifdef YP
88static char *__ypdomain;
89#endif
90
91static struct hostent host;
92static char *host_aliases[MAXALIASES];
93static char hostbuf[BUFSIZ+1];
94static struct in_addr host_addr;
95static FILE *hostf = NULL;
96static int stayopen = 0;
97
98#if PACKETSZ > 1024
99#define MAXPACKET PACKETSZ
100#else
101#define MAXPACKET 1024
102#endif
103
104typedef union {
105 HEADER hdr;
106 u_char buf[MAXPACKET];
107} querybuf;
108
109typedef union {
110 int32_t al;
111 char ac;
112} align;
113
114static int qcomp __P((struct in_addr **, struct in_addr **));
115static struct hostent *getanswer __P((querybuf *, int, int));
116
117extern int h_errno;
118
119static struct hostent *
120getanswer(answer, anslen, iquery)
121 querybuf *answer;
122 int anslen;
123 int iquery;
124{
125 register HEADER *hp;
126 register u_char *cp;
127 register int n;
128 u_char *eom;
129 char *bp, **ap;
130 int type, class, buflen, ancount, qdcount;
131 int haveanswer, getclass = C_ANY;
132 char **hap;
133
134 eom = answer->buf + anslen;
135 /*
136 * find first satisfactory answer
137 */
138 hp = &answer->hdr;
139 ancount = ntohs(hp->ancount);
140 qdcount = ntohs(hp->qdcount);
141 bp = hostbuf;
142 buflen = sizeof(hostbuf);
143 cp = answer->buf + sizeof(HEADER);
144 if (qdcount) {
145 if (iquery) {
146 if ((n = dn_expand((u_char *)answer->buf,
147 (u_char *)eom, (u_char *)cp, (u_char *)bp,
148 buflen)) < 0) {
149 h_errno = NO_RECOVERY;
150 return ((struct hostent *) NULL);
151 }
152 cp += n + QFIXEDSZ;
153 host.h_name = bp;
154 n = strlen(bp) + 1;
155 bp += n;
156 buflen -= n;
157 } else
158 cp += __dn_skipname(cp, eom) + QFIXEDSZ;
159 while (--qdcount > 0)
160 cp += __dn_skipname(cp, eom) + QFIXEDSZ;
161 } else if (iquery) {
162 if (hp->aa)
163 h_errno = HOST_NOT_FOUND;
164 else
165 h_errno = TRY_AGAIN;
166 return ((struct hostent *) NULL);
167 }
168 ap = host_aliases;
169 *ap = NULL;
170 host.h_aliases = host_aliases;
171 hap = h_addr_ptrs;
172 *hap = NULL;
173 host.h_addr_list = h_addr_ptrs;
174 haveanswer = 0;
175 while (--ancount >= 0 && cp < eom) {
176 if ((n = dn_expand((u_char *)answer->buf, (u_char *)eom,
177 (u_char *)cp, (u_char *)bp, buflen)) < 0)
178 break;
179 cp += n;
180 type = _getshort(cp);
181 cp += sizeof(u_int16_t);
182 class = _getshort(cp);
183 cp += sizeof(u_int16_t) + sizeof(u_int32_t);
184 n = _getshort(cp);
185 cp += sizeof(u_int16_t);
186 if (type == T_CNAME) {
187 cp += n;
188 if (ap >= &host_aliases[MAXALIASES-1])
189 continue;
190 *ap++ = bp;
191 n = strlen(bp) + 1;
192 bp += n;
193 buflen -= n;
194 continue;
195 }
196 if (iquery && type == T_PTR) {
197 if ((n = dn_expand((u_char *)answer->buf,
198 (u_char *)eom, (u_char *)cp, (u_char *)bp,
199 buflen)) < 0)
200 break;
201 cp += n;
202 host.h_name = bp;
203 return(&host);
204 }
205 if (iquery || type != T_A) {
206#ifdef DEBUG
207 if (_res.options & RES_DEBUG)
208 printf("unexpected answer type %d, size %d\n",
209 type, n);
210#endif
211 cp += n;
212 continue;
213 }
214 if (haveanswer) {
215 if (n != host.h_length) {
216 cp += n;
217 continue;
218 }
219 if (class != getclass) {
220 cp += n;
221 continue;
222 }
223 } else {
224 host.h_length = n;
225 getclass = class;
226 host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
227 if (!iquery) {
228 host.h_name = bp;
229 bp += strlen(bp) + 1;
230 }
231 }
232
233 bp += sizeof(align) - ((u_long)bp % sizeof(align));
234
235 if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
236#ifdef DEBUG
237 if (_res.options & RES_DEBUG)
238 printf("size (%d) too big\n", n);
239#endif
240 break;
241 }
242 bcopy(cp, *hap++ = bp, n);
243 bp +=n;
244 cp += n;
245 haveanswer++;
246 }
247 if (haveanswer) {
248 *ap = NULL;
249 *hap = NULL;
250 if (_res.nsort) {
251 qsort(host.h_addr_list, haveanswer,
252 sizeof(struct in_addr),
253 (int (*)__P((const void *, const void *)))qcomp);
254 }
255 return (&host);
256 } else {
257 h_errno = TRY_AGAIN;
258 return ((struct hostent *) NULL);
259 }
260}
261
262struct hostent *
263gethostbyname(name)
264 const char *name;
265{
266 querybuf buf;
267 register const char *cp;
268 int n, i;
269 extern struct hostent *_gethtbyname(), *_yp_gethtbyname();
270 register struct hostent *hp;
271 char lookups[MAXDNSLUS];
272
273 /*
274 * disallow names consisting only of digits/dots, unless
275 * they end in a dot.
276 */
277 if (isdigit(name[0]))
278 for (cp = name;; ++cp) {
279 if (!*cp) {
280 if (*--cp == '.')
281 break;
282 /*
283 * All-numeric, no dot at the end.
284 * Fake up a hostent as if we'd actually
285 * done a lookup.
286 */
287 if (!inet_aton(name, &host_addr)) {
288 h_errno = HOST_NOT_FOUND;
289 return((struct hostent *) NULL);
290 }
291 host.h_name = (char *)name;
292 host.h_aliases = host_aliases;
293 host_aliases[0] = NULL;
294 host.h_addrtype = AF_INET;
295 host.h_length = sizeof(u_int32_t);
296 h_addr_ptrs[0] = (char *)&host_addr;
297 h_addr_ptrs[1] = NULL;
298 host.h_addr_list = h_addr_ptrs;
299 return (&host);
300 }
301 if (!isdigit(*cp) && *cp != '.')
302 break;
303 }
304
305 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
306 return (_gethtbyname(name));
307
308 bcopy(_res.lookups, lookups, sizeof lookups);
309 if (lookups[0] == '\0')
310 strncpy(lookups, "bf", sizeof lookups);
311
312 hp = (struct hostent *)NULL;
313 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
314 switch (lookups[i]) {
315#ifdef YP
316 case 'y':
317 hp = _yp_gethtbyname(name);
318 break;
319#endif
320 case 'b':
321 if ((n = res_search(name, C_IN, T_A, buf.buf,
322 sizeof(buf))) < 0) {
323#ifdef DEBUG
324 if (_res.options & RES_DEBUG)
325 printf("res_search failed\n");
326#endif
327 break;
328 }
329 hp = getanswer(&buf, n, 0);
330 break;
331 case 'f':
332 hp = _gethtbyname(name);
333 break;
334 }
335 }
336 return (hp);
337}
338
339struct hostent *
340gethostbyaddr(addr, len, type)
341 const char *addr;
342 int len, type;
343{
344 int n, i;
345 querybuf buf;
346 register struct hostent *hp;
347 char qbuf[MAXDNAME];
348 extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr();
349 char lookups[MAXDNSLUS];
350
351 if (type != AF_INET)
352 return ((struct hostent *) NULL);
353 (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
354 ((unsigned)addr[3] & 0xff),
355 ((unsigned)addr[2] & 0xff),
356 ((unsigned)addr[1] & 0xff),
357 ((unsigned)addr[0] & 0xff));
358
359 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
360 return (_gethtbyaddr(addr, len, type));
361
362 bcopy(_res.lookups, lookups, sizeof lookups);
363 if (lookups[0] == '\0')
364 strncpy(lookups, "bf", sizeof lookups);
365
366 hp = (struct hostent *)NULL;
367 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
368 switch (lookups[i]) {
369#ifdef YP
370 case 'y':
371 hp = _yp_gethtbyaddr(addr, len, type);
372 break;
373#endif
374 case 'b':
375 n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf));
376 if (n < 0) {
377#ifdef DEBUG
378 if (_res.options & RES_DEBUG)
379 printf("res_query failed\n");
380#endif
381 break;
382 }
383 hp = getanswer(&buf, n, 1);
384 if (hp == NULL)
385 break;
386 hp->h_addrtype = type;
387 hp->h_length = len;
388 h_addr_ptrs[0] = (char *)&host_addr;
389 h_addr_ptrs[1] = (char *)0;
390 host_addr = *(struct in_addr *)addr;
391 break;
392 case 'f':
393 hp = _gethtbyaddr(addr, len, type);
394 break;
395 }
396 }
397 return (hp);
398}
399
400void
401_sethtent(f)
402 int f;
403{
404 if (hostf == NULL)
405 hostf = fopen(_PATH_HOSTS, "r" );
406 else
407 rewind(hostf);
408 stayopen = f;
409}
410
411void
412_endhtent()
413{
414 if (hostf && !stayopen) {
415 (void) fclose(hostf);
416 hostf = NULL;
417 }
418}
419
420struct hostent *
421_gethtent()
422{
423 char *p;
424 register char *cp, **q;
425
426 if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL)
427 return (NULL);
428again:
429 if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
430 return (NULL);
431 if (*p == '#')
432 goto again;
433 cp = strpbrk(p, "#\n");
434 if (cp == NULL)
435 goto again;
436 *cp = '\0';
437 cp = strpbrk(p, " \t");
438 if (cp == NULL)
439 goto again;
440 *cp++ = '\0';
441 /* THIS STUFF IS INTERNET SPECIFIC */
442 h_addr_ptrs[0] = (char *)&host_addr;
443 h_addr_ptrs[1] = NULL;
444 (void) inet_aton(p, &host_addr);
445 host.h_addr_list = h_addr_ptrs;
446 host.h_length = sizeof(u_int32_t);
447 host.h_addrtype = AF_INET;
448 while (*cp == ' ' || *cp == '\t')
449 cp++;
450 host.h_name = cp;
451 q = host.h_aliases = host_aliases;
452 cp = strpbrk(cp, " \t");
453 if (cp != NULL)
454 *cp++ = '\0';
455 while (cp && *cp) {
456 if (*cp == ' ' || *cp == '\t') {
457 cp++;
458 continue;
459 }
460 if (q < &host_aliases[MAXALIASES - 1])
461 *q++ = cp;
462 cp = strpbrk(cp, " \t");
463 if (cp != NULL)
464 *cp++ = '\0';
465 }
466 *q = NULL;
467 return (&host);
468}
469
470struct hostent *
471_gethtbyname(name)
472 char *name;
473{
474 register struct hostent *p;
475 register char **cp;
476
477 _sethtent(0);
478 while (p = _gethtent()) {
479 if (strcasecmp(p->h_name, name) == 0)
480 break;
481 for (cp = p->h_aliases; *cp != 0; cp++)
482 if (strcasecmp(*cp, name) == 0)
483 goto found;
484 }
485found:
486 _endhtent();
487 if (p==NULL)
488 h_errno = HOST_NOT_FOUND;
489 return (p);
490}
491
492struct hostent *
493_gethtbyaddr(addr, len, type)
494 const char *addr;
495 int len, type;
496{
497 register struct hostent *p;
498
499 _sethtent(0);
500 while (p = _gethtent())
501 if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
502 break;
503 _endhtent();
504 if (p==NULL)
505 h_errno = HOST_NOT_FOUND;
506 return (p);
507}
508
509static int
510qcomp(a1, a2)
511 struct in_addr **a1, **a2;
512{
513 int pos1, pos2;
514
515 for (pos1 = 0; pos1 < _res.nsort; pos1++)
516 if (_res.sort_list[pos1].addr.s_addr ==
517 ((*a1)->s_addr & _res.sort_list[pos1].mask))
518 break;
519 for (pos2 = 0; pos2 < _res.nsort; pos2++)
520 if (_res.sort_list[pos2].addr.s_addr ==
521 ((*a2)->s_addr & _res.sort_list[pos2].mask))
522 break;
523 return pos1 - pos2;
524}
525
526#ifdef YP
527struct hostent *
528_yphostent(line)
529 char *line;
530{
531 static struct in_addr host_addrs[MAXADDRS];
532 char *p = line;
533 char *cp, **q;
534 char **hap;
535 struct in_addr *buf;
536 int more;
537
538 host.h_name = NULL;
539 host.h_addr_list = h_addr_ptrs;
540 host.h_length = sizeof(u_int32_t);
541 host.h_addrtype = AF_INET;
542 hap = h_addr_ptrs;
543 buf = host_addrs;
544 q = host.h_aliases = host_aliases;
545
546nextline:
547 more = 0;
548 cp = strpbrk(p, " \t");
549 if (cp == NULL) {
550 if (host.h_name == NULL)
551 return (NULL);
552 else
553 goto done;
554 }
555 *cp++ = '\0';
556
557 *hap++ = (char *)buf;
558 (void) inet_aton(p, buf++);
559
560 while (*cp == ' ' || *cp == '\t')
561 cp++;
562 p = cp;
563 cp = strpbrk(p, " \t\n");
564 if (cp != NULL) {
565 if (*cp == '\n')
566 more = 1;
567 *cp++ = '\0';
568 }
569 if (!host.h_name)
570 host.h_name = p;
571 else if (strcmp(host.h_name, p)==0)
572 ;
573 else if (q < &host_aliases[MAXALIASES - 1])
574 *q++ = p;
575 p = cp;
576 if (more)
577 goto nextline;
578
579 while (cp && *cp) {
580 if (*cp == ' ' || *cp == '\t') {
581 cp++;
582 continue;
583 }
584 if (*cp == '\n') {
585 cp++;
586 goto nextline;
587 }
588 if (q < &host_aliases[MAXALIASES - 1])
589 *q++ = cp;
590 cp = strpbrk(cp, " \t");
591 if (cp != NULL)
592 *cp++ = '\0';
593 }
594done:
595 *q = NULL;
596 *hap = NULL;
597 return (&host);
598}
599
600struct hostent *
601_yp_gethtbyaddr(addr, len, type)
602 const char *addr;
603 int len, type;
604{
605 struct hostent *hp = (struct hostent *)NULL;
606 static char *__ypcurrent;
607 int __ypcurrentlen, r;
608 char name[sizeof("xxx.xxx.xxx.xxx") + 1];
609
610 if (!__ypdomain) {
611 if (_yp_check(&__ypdomain) == 0)
612 return (hp);
613 }
614 sprintf(name, "%u.%u.%u.%u",
615 ((unsigned)addr[0] & 0xff),
616 ((unsigned)addr[1] & 0xff),
617 ((unsigned)addr[2] & 0xff),
618 ((unsigned)addr[3] & 0xff));
619 if (__ypcurrent)
620 free(__ypcurrent);
621 __ypcurrent = NULL;
622 r = yp_match(__ypdomain, "hosts.byaddr", name,
623 strlen(name), &__ypcurrent, &__ypcurrentlen);
624 if (r==0)
625 hp = _yphostent(__ypcurrent);
626 if (hp==NULL)
627 h_errno = HOST_NOT_FOUND;
628 return (hp);
629}
630
631struct hostent *
632_yp_gethtbyname(name)
633 const char *name;
634{
635 struct hostent *hp = (struct hostent *)NULL;
636 static char *__ypcurrent;
637 int __ypcurrentlen, r;
638
639 if (!__ypdomain) {
640 if (_yp_check(&__ypdomain) == 0)
641 return (hp);
642 }
643 if (__ypcurrent)
644 free(__ypcurrent);
645 __ypcurrent = NULL;
646 r = yp_match(__ypdomain, "hosts.byname", name,
647 strlen(name), &__ypcurrent, &__ypcurrentlen);
648 if (r==0)
649 hp = _yphostent(__ypcurrent);
650 if (hp==NULL)
651 h_errno = HOST_NOT_FOUND;
652 return (hp);
653}
654#endif