2 * ++Copyright++ 1985, 1988
4 * Copyright (c) 1985, 1988 Regents of the University of California.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
35 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
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.
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
56 #if defined(LIBC_SCCS) && !defined(lint)
57 static char sccsid
[] = "@(#)gethostnamadr.c 6.47 (Berkeley) 6/18/92";
58 static char rcsid
[] = "$Id$";
59 #endif /* LIBC_SCCS and not lint */
61 #include <sys/param.h>
62 #include <sys/socket.h>
63 #include <netinet/in.h>
64 #include <arpa/inet.h>
65 #include <arpa/nameser.h>
71 #include "../conf/portability.h"
76 static char *h_addr_ptrs
[MAXADDRS
+ 1];
78 static struct hostent host
;
79 static char *host_aliases
[MAXALIASES
];
80 static char hostbuf
[BUFSIZ
+1];
81 static struct in_addr host_addr
;
82 static FILE *hostf
= NULL
;
83 static char hostaddr
[MAXADDRS
];
84 static char *host_addrs
[2];
85 static int stayopen
= 0;
89 #define MAXPACKET PACKETSZ
91 #define MAXPACKET 1024
96 u_char buf
[MAXPACKET
];
106 static struct hostent
*
107 getanswer(answer
, anslen
, iquery
)
117 int type
, class, buflen
, ancount
, qdcount
;
118 int haveanswer
, getclass
= C_ANY
;
121 eom
= answer
->buf
+ anslen
;
123 * find first satisfactory answer
126 ancount
= ntohs(hp
->ancount
);
127 qdcount
= ntohs(hp
->qdcount
);
129 buflen
= sizeof(hostbuf
);
130 cp
= answer
->buf
+ sizeof(HEADER
);
133 if ((n
= dn_expand((u_char
*)answer
->buf
,
134 (u_char
*)eom
, (u_char
*)cp
, (u_char
*)bp
,
136 h_errno
= NO_RECOVERY
;
137 return ((struct hostent
*) NULL
);
145 cp
+= __dn_skipname(cp
, eom
) + QFIXEDSZ
;
146 while (--qdcount
> 0)
147 cp
+= __dn_skipname(cp
, eom
) + QFIXEDSZ
;
150 h_errno
= HOST_NOT_FOUND
;
153 return ((struct hostent
*) NULL
);
157 host
.h_aliases
= host_aliases
;
160 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
161 host
.h_addr_list
= h_addr_ptrs
;
164 while (--ancount
>= 0 && cp
< eom
) {
165 if ((n
= dn_expand((u_char
*)answer
->buf
, (u_char
*)eom
,
166 (u_char
*)cp
, (u_char
*)bp
, buflen
)) < 0)
169 type
= _getshort(cp
);
170 cp
+= sizeof(u_short
);
171 class = _getshort(cp
);
172 cp
+= sizeof(u_short
) + sizeof(u_int32_t
);
174 cp
+= sizeof(u_short
);
175 if (type
== T_CNAME
) {
177 if (ap
>= &host_aliases
[MAXALIASES
-1])
185 if (iquery
&& type
== T_PTR
) {
186 if ((n
= dn_expand((u_char
*)answer
->buf
,
187 (u_char
*)eom
, (u_char
*)cp
, (u_char
*)bp
,
196 if (iquery
|| type
!= T_A
) {
198 if (_res
.options
& RES_DEBUG
)
199 printf("unexpected answer type %d, size %d\n",
206 if (n
!= host
.h_length
) {
210 if (class != getclass
) {
217 host
.h_addrtype
= (class == C_IN
) ? AF_INET
: AF_UNSPEC
;
220 bp
+= strlen(bp
) + 1;
224 bp
+= sizeof(align
) - ((u_int32_t
)bp
% sizeof(align
));
226 if (bp
+ n
>= &hostbuf
[sizeof(hostbuf
)]) {
228 if (_res
.options
& RES_DEBUG
)
229 printf("size (%d) too big\n", n
);
233 bcopy(cp
, *hap
++ = bp
, n
);
240 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
243 host
.h_addr
= h_addr_ptrs
[0];
248 return ((struct hostent
*) NULL
);
257 register const char *cp
;
259 extern struct hostent
*_gethtbyname();
262 * disallow names consisting only of digits/dots, unless
265 if (isdigit(name
[0]))
266 for (cp
= name
;; ++cp
) {
271 * All-numeric, no dot at the end.
272 * Fake up a hostent as if we'd actually
275 if (!inet_aton(name
, &host_addr
)) {
276 h_errno
= HOST_NOT_FOUND
;
277 return((struct hostent
*) NULL
);
279 host
.h_name
= (char *)name
;
280 host
.h_aliases
= host_aliases
;
281 host_aliases
[0] = NULL
;
282 host
.h_addrtype
= AF_INET
;
283 host
.h_length
= sizeof(u_int32_t
);
284 h_addr_ptrs
[0] = (char *)&host_addr
;
285 h_addr_ptrs
[1] = (char *)0;
286 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
287 host
.h_addr_list
= h_addr_ptrs
;
289 host
.h_addr
= h_addr_ptrs
[0];
293 if (!isdigit(*cp
) && *cp
!= '.')
297 if ((n
= res_search(name
, C_IN
, T_A
, buf
.buf
, sizeof(buf
))) < 0) {
299 if (_res
.options
& RES_DEBUG
)
300 printf("res_search failed\n");
302 if (errno
== ECONNREFUSED
)
303 return (_gethtbyname(name
));
305 return ((struct hostent
*) NULL
);
307 return (getanswer(&buf
, n
, 0));
311 gethostbyaddr(addr
, len
, type
)
317 register struct hostent
*hp
;
319 extern struct hostent
*_gethtbyaddr();
322 return ((struct hostent
*) NULL
);
323 (void)sprintf(qbuf
, "%u.%u.%u.%u.in-addr.arpa",
324 ((unsigned)addr
[3] & 0xff),
325 ((unsigned)addr
[2] & 0xff),
326 ((unsigned)addr
[1] & 0xff),
327 ((unsigned)addr
[0] & 0xff));
328 n
= res_query(qbuf
, C_IN
, T_PTR
, (char *)&buf
, sizeof(buf
));
331 if (_res
.options
& RES_DEBUG
)
332 printf("res_query failed\n");
334 if (errno
== ECONNREFUSED
)
335 return (_gethtbyaddr(addr
, len
, type
));
336 return ((struct hostent
*) NULL
);
338 hp
= getanswer(&buf
, n
, 1);
340 return ((struct hostent
*) NULL
);
341 hp
->h_addrtype
= type
;
343 h_addr_ptrs
[0] = (char *)&host_addr
;
344 h_addr_ptrs
[1] = (char *)0;
345 host_addr
= *(struct in_addr
*)addr
;
346 #if BSD < 43 && !defined(h_addr) /* new-style hostent structure */
347 hp
->h_addr
= h_addr_ptrs
[0];
357 hostf
= fopen(_PATH_HOSTS
, "r" );
366 if (hostf
&& !stayopen
) {
367 (void) fclose(hostf
);
376 register char *cp
, **q
;
378 if (hostf
== NULL
&& (hostf
= fopen(_PATH_HOSTS
, "r" )) == NULL
)
381 if ((p
= fgets(hostbuf
, BUFSIZ
, hostf
)) == NULL
)
385 cp
= strpbrk(p
, "#\n");
389 cp
= strpbrk(p
, " \t");
393 /* THIS STUFF IS INTERNET SPECIFIC */
394 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
395 host
.h_addr_list
= host_addrs
;
397 host
.h_addr
= hostaddr
;
398 *((u_int32_t
*)host
.h_addr
) = inet_addr(p
);
399 host
.h_length
= sizeof (u_int32_t
);
400 host
.h_addrtype
= AF_INET
;
401 while (*cp
== ' ' || *cp
== '\t')
404 q
= host
.h_aliases
= host_aliases
;
405 cp
= strpbrk(cp
, " \t");
409 if (*cp
== ' ' || *cp
== '\t') {
413 if (q
< &host_aliases
[MAXALIASES
- 1])
415 cp
= strpbrk(cp
, " \t");
427 register struct hostent
*p
;
431 while (p
= _gethtent()) {
432 if (strcasecmp(p
->h_name
, name
) == 0)
434 for (cp
= p
->h_aliases
; *cp
!= 0; cp
++)
435 if (strcasecmp(*cp
, name
) == 0)
444 _gethtbyaddr(addr
, len
, type
)
448 register struct hostent
*p
;
451 while (p
= _gethtent())
452 if (p
->h_addrtype
== type
&& !bcmp(p
->h_addr
, addr
, len
))
458 #if defined(BSD43_BSD43_NFS) || defined(sun)
459 /* some libc's out there are bound internally to these names (UMIPS) */
461 ht_sethostent(stayopen
)
474 ht_gethostbyname(name
)
477 return _gethtbyname(name
);
481 ht_gethostbyaddr(addr
, len
, type
)
485 return _gethtbyaddr(addr
, len
, type
);
501 dn_skipname(comp_dn
, eom
)
502 const u_char
*comp_dn
, *eom
;
504 return __dn_skipname(comp_dn
, eom
);
506 #endif /*old-style libc with yp junk in it*/