Home | History | Annotate | Line # | Download | only in libhack
gethost.c revision 1.9
      1  1.9  christos /*	$NetBSD: gethost.c,v 1.9 2013/08/20 15:44:17 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.2       gwr /*
     53  1.2       gwr  * Copied from:  lib/libc/net/gethostnamadr.c
     54  1.2       gwr  * and then gutted, leaving only /etc/hosts support.
     55  1.2       gwr  */
     56  1.5        pk 
     57  1.5        pk #include <sys/cdefs.h>
     58  1.5        pk 
     59  1.7   tsutsui #ifdef __weak_alias
     60  1.7   tsutsui #define gethostbyaddr		_gethostbyaddr
     61  1.7   tsutsui #define gethostbyname		_gethostbyname
     62  1.5        pk #endif
     63  1.1       gwr 
     64  1.1       gwr #include <sys/param.h>
     65  1.1       gwr #include <sys/socket.h>
     66  1.1       gwr #include <netinet/in.h>
     67  1.1       gwr #include <arpa/inet.h>
     68  1.1       gwr #include <arpa/nameser.h>
     69  1.1       gwr #include <netdb.h>
     70  1.1       gwr #include <resolv.h>
     71  1.1       gwr #include <stdio.h>
     72  1.1       gwr #include <ctype.h>
     73  1.1       gwr #include <errno.h>
     74  1.1       gwr #include <string.h>
     75  1.7   tsutsui 
     76  1.7   tsutsui #ifdef __weak_alias
     77  1.7   tsutsui __weak_alias(gethostbyaddr,_gethostbyaddr);
     78  1.7   tsutsui __weak_alias(gethostbyname,_gethostbyname);
     79  1.7   tsutsui #endif
     80  1.1       gwr 
     81  1.1       gwr #define	MAXALIASES	35
     82  1.1       gwr #define	MAXADDRS	35
     83  1.1       gwr 
     84  1.1       gwr static char *h_addr_ptrs[MAXADDRS + 1];
     85  1.1       gwr 
     86  1.1       gwr static struct hostent host;
     87  1.1       gwr static char *host_aliases[MAXALIASES];
     88  1.1       gwr static char hostbuf[BUFSIZ+1];
     89  1.1       gwr static struct in_addr host_addr;
     90  1.1       gwr static FILE *hostf = NULL;
     91  1.1       gwr static int stayopen = 0;
     92  1.1       gwr 
     93  1.9  christos void _sethtent(int);
     94  1.9  christos void _endhtent(void);
     95  1.9  christos struct hostent *_gethtent(void);
     96  1.9  christos struct hostent *_gethtbyname(const char *);
     97  1.9  christos struct hostent *_gethtbyaddr(const void *, socklen_t, int);
     98  1.4  sommerfe 
     99  1.4  sommerfe 
    100  1.1       gwr #if PACKETSZ > 1024
    101  1.1       gwr #define	MAXPACKET	PACKETSZ
    102  1.1       gwr #else
    103  1.1       gwr #define	MAXPACKET	1024
    104  1.1       gwr #endif
    105  1.1       gwr 
    106  1.1       gwr extern int h_errno;
    107  1.1       gwr 
    108  1.1       gwr struct hostent *
    109  1.9  christos gethostbyname(const char *name)
    110  1.1       gwr {
    111  1.9  christos 	const char *cp;
    112  1.1       gwr 
    113  1.1       gwr 	/*
    114  1.1       gwr 	 * disallow names consisting only of digits/dots, unless
    115  1.1       gwr 	 * they end in a dot.
    116  1.1       gwr 	 */
    117  1.9  christos 	if (isdigit((unsigned char)name[0]))
    118  1.1       gwr 		for (cp = name;; ++cp) {
    119  1.1       gwr 			if (!*cp) {
    120  1.1       gwr 				if (*--cp == '.')
    121  1.1       gwr 					break;
    122  1.1       gwr 				/*
    123  1.1       gwr 				 * All-numeric, no dot at the end.
    124  1.1       gwr 				 * Fake up a hostent as if we'd actually
    125  1.1       gwr 				 * done a lookup.
    126  1.1       gwr 				 */
    127  1.1       gwr 				if (!inet_aton(name, &host_addr)) {
    128  1.1       gwr 					h_errno = HOST_NOT_FOUND;
    129  1.1       gwr 					return((struct hostent *) NULL);
    130  1.1       gwr 				}
    131  1.1       gwr 				host.h_name = (char *)name;
    132  1.1       gwr 				host.h_aliases = host_aliases;
    133  1.1       gwr 				host_aliases[0] = NULL;
    134  1.1       gwr 				host.h_addrtype = AF_INET;
    135  1.1       gwr 				host.h_length = sizeof(u_int32_t);
    136  1.1       gwr 				h_addr_ptrs[0] = (char *)&host_addr;
    137  1.1       gwr 				h_addr_ptrs[1] = NULL;
    138  1.1       gwr 				host.h_addr_list = h_addr_ptrs;
    139  1.9  christos 				return &host;
    140  1.1       gwr 			}
    141  1.9  christos 			if (!isdigit((unsigned char)*cp) && *cp != '.')
    142  1.1       gwr 				break;
    143  1.1       gwr 		}
    144  1.1       gwr 
    145  1.1       gwr 	/* XXX - Force host table lookup. */
    146  1.9  christos 	return _gethtbyname(name);
    147  1.1       gwr }
    148  1.1       gwr 
    149  1.1       gwr struct hostent *
    150  1.9  christos gethostbyaddr(const void *addr, socklen_t len, int type)
    151  1.1       gwr {
    152  1.9  christos #if 0
    153  1.1       gwr 	char qbuf[MAXDNAME];
    154  1.9  christos #endif
    155  1.2       gwr 
    156  1.1       gwr 	if (type != AF_INET)
    157  1.9  christos 		return NULL;
    158  1.9  christos #if 0
    159  1.9  christos 	(void)snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa",
    160  1.9  christos 	    ((unsigned)addr[3] & 0xff), ((unsigned)addr[2] & 0xff),
    161  1.9  christos 	    ((unsigned)addr[1] & 0xff), ((unsigned)addr[0] & 0xff));
    162  1.9  christos #endif
    163  1.1       gwr 
    164  1.1       gwr 	/* XXX - Force host table lookup. */
    165  1.9  christos 	return _gethtbyaddr(addr, len, type);
    166  1.1       gwr }
    167  1.1       gwr 
    168  1.1       gwr void
    169  1.9  christos _sethtent(int f)
    170  1.1       gwr {
    171  1.1       gwr 	if (hostf == NULL)
    172  1.1       gwr 		hostf = fopen(_PATH_HOSTS, "r" );
    173  1.1       gwr 	else
    174  1.1       gwr 		rewind(hostf);
    175  1.1       gwr 	stayopen = f;
    176  1.1       gwr }
    177  1.1       gwr 
    178  1.1       gwr void
    179  1.9  christos _endhtent(void)
    180  1.1       gwr {
    181  1.1       gwr 	if (hostf && !stayopen) {
    182  1.1       gwr 		(void) fclose(hostf);
    183  1.1       gwr 		hostf = NULL;
    184  1.1       gwr 	}
    185  1.1       gwr }
    186  1.1       gwr 
    187  1.1       gwr struct hostent *
    188  1.9  christos _gethtent(void)
    189  1.1       gwr {
    190  1.1       gwr 	char *p;
    191  1.9  christos 	char *cp, **q;
    192  1.1       gwr 
    193  1.1       gwr 	if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL)
    194  1.9  christos 		return NULL;
    195  1.1       gwr again:
    196  1.1       gwr 	if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
    197  1.9  christos 		return NULL;
    198  1.1       gwr 	if (*p == '#')
    199  1.1       gwr 		goto again;
    200  1.1       gwr 	cp = strpbrk(p, "#\n");
    201  1.1       gwr 	if (cp == NULL)
    202  1.1       gwr 		goto again;
    203  1.1       gwr 	*cp = '\0';
    204  1.1       gwr 	cp = strpbrk(p, " \t");
    205  1.1       gwr 	if (cp == NULL)
    206  1.1       gwr 		goto again;
    207  1.1       gwr 	*cp++ = '\0';
    208  1.1       gwr 	/* THIS STUFF IS INTERNET SPECIFIC */
    209  1.1       gwr 	h_addr_ptrs[0] = (char *)&host_addr;
    210  1.1       gwr 	h_addr_ptrs[1] = NULL;
    211  1.1       gwr 	(void) inet_aton(p, &host_addr);
    212  1.1       gwr 	host.h_addr_list = h_addr_ptrs;
    213  1.1       gwr 	host.h_length = sizeof(u_int32_t);
    214  1.1       gwr 	host.h_addrtype = AF_INET;
    215  1.1       gwr 	while (*cp == ' ' || *cp == '\t')
    216  1.1       gwr 		cp++;
    217  1.1       gwr 	host.h_name = cp;
    218  1.1       gwr 	q = host.h_aliases = host_aliases;
    219  1.1       gwr 	cp = strpbrk(cp, " \t");
    220  1.1       gwr 	if (cp != NULL)
    221  1.1       gwr 		*cp++ = '\0';
    222  1.1       gwr 	while (cp && *cp) {
    223  1.1       gwr 		if (*cp == ' ' || *cp == '\t') {
    224  1.1       gwr 			cp++;
    225  1.1       gwr 			continue;
    226  1.1       gwr 		}
    227  1.1       gwr 		if (q < &host_aliases[MAXALIASES - 1])
    228  1.1       gwr 			*q++ = cp;
    229  1.1       gwr 		cp = strpbrk(cp, " \t");
    230  1.1       gwr 		if (cp != NULL)
    231  1.1       gwr 			*cp++ = '\0';
    232  1.1       gwr 	}
    233  1.1       gwr 	*q = NULL;
    234  1.9  christos 	return &host;
    235  1.1       gwr }
    236  1.1       gwr 
    237  1.1       gwr struct hostent *
    238  1.9  christos _gethtbyname(const char *name)
    239  1.1       gwr {
    240  1.9  christos 	struct hostent *p;
    241  1.9  christos 	char **cp;
    242  1.1       gwr 
    243  1.1       gwr 	_sethtent(0);
    244  1.4  sommerfe 	while ((p = _gethtent()) != NULL) {
    245  1.1       gwr 		if (strcasecmp(p->h_name, name) == 0)
    246  1.1       gwr 			break;
    247  1.1       gwr 		for (cp = p->h_aliases; *cp != 0; cp++)
    248  1.1       gwr 			if (strcasecmp(*cp, name) == 0)
    249  1.1       gwr 				goto found;
    250  1.1       gwr 	}
    251  1.1       gwr found:
    252  1.1       gwr 	_endhtent();
    253  1.9  christos 	if (p == NULL)
    254  1.1       gwr 		h_errno = HOST_NOT_FOUND;
    255  1.9  christos 	return p;
    256  1.1       gwr }
    257  1.1       gwr 
    258  1.1       gwr struct hostent *
    259  1.9  christos _gethtbyaddr(const void *addr, socklen_t len, int type)
    260  1.1       gwr {
    261  1.9  christos 	struct hostent *p;
    262  1.1       gwr 
    263  1.1       gwr 	_sethtent(0);
    264  1.4  sommerfe 	while ((p = _gethtent()) != NULL)
    265  1.3     perry 		if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len))
    266  1.1       gwr 			break;
    267  1.1       gwr 	_endhtent();
    268  1.9  christos 	if (p == NULL)
    269  1.1       gwr 		h_errno = HOST_NOT_FOUND;
    270  1.9  christos 	return p;
    271  1.1       gwr }
    272  1.1       gwr 
    273