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