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