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