Home | History | Annotate | Line # | Download | only in libhack
      1 /*	$NetBSD: gethost.c,v 1.12 2013/12/21 20:10:02 christos 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. Neither the name of the University nor the names of its contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  * -
     31  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
     32  *
     33  * Permission to use, copy, modify, and distribute this software for any
     34  * purpose with or without fee is hereby granted, provided that the above
     35  * copyright notice and this permission notice appear in all copies, and that
     36  * the name of Digital Equipment Corporation not be used in advertising or
     37  * publicity pertaining to distribution of the document or software without
     38  * specific, written prior permission.
     39  *
     40  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
     41  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
     42  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
     43  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
     44  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
     45  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
     46  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     47  * SOFTWARE.
     48  * -
     49  * --Copyright--
     50  */
     51 
     52 /* Provide just /etc/hosts lookup support */
     53 
     54 #include <sys/cdefs.h>
     55 
     56 #ifdef __weak_alias
     57 #define gethostbyaddr		_gethostbyaddr
     58 #define gethostbyname		_gethostbyname
     59 #endif
     60 
     61 #include <netdb.h>
     62 #include <string.h>
     63 #include <nsswitch.h>
     64 #include <errno.h>
     65 #include <arpa/nameser.h>
     66 #include <arpa/inet.h>
     67 #include <sys/socket.h>
     68 
     69 #include "hostent.h"
     70 
     71 #ifdef __weak_alias
     72 __weak_alias(gethostbyaddr,_gethostbyaddr);
     73 __weak_alias(gethostbyname,_gethostbyname);
     74 #endif
     75 
     76 int h_errno;
     77 FILE *_h_file;
     78 static struct hostent h_ent;
     79 static char h_buf[4096];
     80 
     81 static struct hostent *
     82 getby(int (*f)(void *, void *, va_list), struct getnamaddr *info, ...)
     83 {
     84         va_list ap;
     85         int e;
     86 
     87         va_start(ap, info);
     88         e = (*f)(info, NULL, ap);
     89         va_end(ap);
     90         switch (e) {
     91         case NS_SUCCESS:
     92                 return info->hp;
     93         default:
     94 		return NULL;
     95         }
     96 }
     97 
     98 struct hostent *
     99 gethostbyname_r(const char *name, struct hostent *hp, char *buf, size_t bufsiz,
    100     int *he)
    101 {
    102 	struct getnamaddr info;
    103 	info.hp = hp;
    104 	info.buf = buf;
    105 	info.buflen = bufsiz;
    106 	info.he = he;
    107 	return getby(_hf_gethtbyname, &info, name, 0, AF_INET);
    108 }
    109 
    110 
    111 struct hostent *
    112 gethostbyname(const char *name)
    113 {
    114 	return gethostbyname_r(name, &h_ent, h_buf, sizeof(h_buf), &h_errno);
    115 }
    116 
    117 struct hostent *
    118 gethostbyaddr_r(const void *addr, socklen_t len, int type, struct hostent *hp,
    119     char *buf, size_t bufsiz, int *he)
    120 {
    121 	struct getnamaddr info;
    122 	info.hp = hp;
    123 	info.buf = buf;
    124 	info.buflen = bufsiz;
    125 	info.he = he;
    126 	return getby(_hf_gethtbyaddr, &info, addr, len, type);
    127 }
    128 
    129 struct hostent *
    130 gethostbyaddr(const void *addr, socklen_t len, int type)
    131 {
    132 	return gethostbyaddr_r(addr, len, type, &h_ent, h_buf, sizeof(h_buf),
    133 	    &h_errno);
    134 }
    135 
    136 struct hostent *
    137 gethostent_r(FILE *hf, struct hostent *hent, char *buf, size_t buflen, int *he)
    138 {
    139 	char *p, *name;
    140 	char *cp, **q;
    141 	int af, len;
    142 	size_t llen, anum;
    143 	char *aliases[MAXALIASES];
    144 	struct in6_addr host_addr;
    145 
    146 	if (hf == NULL) {
    147 		*he = NETDB_INTERNAL;
    148 		errno = EINVAL;
    149 		return NULL;
    150 	}
    151  again:
    152 	if ((p = fgetln(hf, &llen)) == NULL) {
    153 		*he = HOST_NOT_FOUND;
    154 		return NULL;
    155 	}
    156 	if (llen < 1)
    157 		goto again;
    158 	if (*p == '#')
    159 		goto again;
    160 	p[llen] = '\0';
    161 	if (!(cp = strpbrk(p, "#\n")))
    162 		goto again;
    163 	*cp = '\0';
    164 	if (!(cp = strpbrk(p, " \t")))
    165 		goto again;
    166 	*cp++ = '\0';
    167 	if (inet_pton(AF_INET6, p, &host_addr) > 0) {
    168 		af = AF_INET6;
    169 		len = NS_IN6ADDRSZ;
    170 	} else if (inet_pton(AF_INET, p, &host_addr) > 0) {
    171 #if 0
    172 		res_state res = __res_get_state();
    173 		if (res == NULL)
    174 			return NULL;
    175 		if (res->options & RES_USE_INET6) {
    176 			map_v4v6_address(buf, buf);
    177 			af = AF_INET6;
    178 			len = NS_IN6ADDRSZ;
    179 		} else {
    180 #endif
    181 			af = AF_INET;
    182 			len = NS_INADDRSZ;
    183 #if 0
    184 		}
    185 		__res_put_state(res);
    186 #endif
    187 	} else {
    188 		goto again;
    189 	}
    190 	/* if this is not something we're looking for, skip it. */
    191 	if (hent->h_addrtype != 0 && hent->h_addrtype != af)
    192 		goto again;
    193 	if (hent->h_length != 0 && hent->h_length != len)
    194 		goto again;
    195 
    196 	while (*cp == ' ' || *cp == '\t')
    197 		cp++;
    198 	if ((cp = strpbrk(name = cp, " \t")) != NULL)
    199 		*cp++ = '\0';
    200 	q = aliases;
    201 	while (cp && *cp) {
    202 		if (*cp == ' ' || *cp == '\t') {
    203 			cp++;
    204 			continue;
    205 		}
    206 		if (q >= &aliases[__arraycount(aliases)])
    207 			goto nospc;
    208 		*q++ = cp;
    209 		if ((cp = strpbrk(cp, " \t")) != NULL)
    210 			*cp++ = '\0';
    211 	}
    212 	hent->h_length = len;
    213 	hent->h_addrtype = af;
    214 	HENT_ARRAY(hent->h_addr_list, 1, buf, buflen);
    215 	anum = (size_t)(q - aliases);
    216 	HENT_ARRAY(hent->h_aliases, anum, buf, buflen);
    217 	HENT_COPY(hent->h_addr_list[0], &host_addr, hent->h_length, buf,
    218 	    buflen);
    219 	hent->h_addr_list[1] = NULL;
    220 
    221 	HENT_SCOPY(hent->h_name, name, buf, buflen);
    222 	for (size_t i = 0; i < anum; i++)
    223 		HENT_SCOPY(hent->h_aliases[i], aliases[i], buf, buflen);
    224 	hent->h_aliases[anum] = NULL;
    225 
    226 	*he = NETDB_SUCCESS;
    227 	return hent;
    228 nospc:
    229 	errno = ENOSPC;
    230 	*he = NETDB_INTERNAL;
    231 	return NULL;
    232 }
    233