1 /* $NetBSD: gethost.c,v 1.5 2000/01/14 13:52:13 pk 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 #if defined(__weak_alias) 64 /* From namespace.h: */ 65 #define gethostbyaddr _gethostbyaddr 66 #define gethostbyname _gethostbyname 67 #define gethostname _gethostname 68 69 __weak_alias(gethostbyaddr,_gethostbyaddr); 70 __weak_alias(gethostbyname,_gethostbyname); 71 __weak_alias(gethostbyname2,gethostbyname); 72 #endif 73 74 #include <sys/param.h> 75 #include <sys/socket.h> 76 #include <netinet/in.h> 77 #include <arpa/inet.h> 78 #include <arpa/nameser.h> 79 #include <netdb.h> 80 #include <resolv.h> 81 #include <stdio.h> 82 #include <ctype.h> 83 #include <errno.h> 84 #include <string.h> 85 86 #define MAXALIASES 35 87 #define MAXADDRS 35 88 89 static char *h_addr_ptrs[MAXADDRS + 1]; 90 91 static struct hostent host; 92 static char *host_aliases[MAXALIASES]; 93 static char hostbuf[BUFSIZ+1]; 94 static struct in_addr host_addr; 95 static FILE *hostf = NULL; 96 static int stayopen = 0; 97 98 void _sethtent __P((int)); 99 void _endhtent __P((void)); 100 struct hostent *_gethtent __P((void)); 101 struct hostent *_gethtbyname __P((const char *)); 102 struct hostent *_gethtbyaddr __P((const char *, int, int)); 103 104 105 #if PACKETSZ > 1024 106 #define MAXPACKET PACKETSZ 107 #else 108 #define MAXPACKET 1024 109 #endif 110 111 extern int h_errno; 112 113 struct hostent * 114 gethostbyname(name) 115 const char *name; 116 { 117 register const char *cp; 118 119 /* 120 * disallow names consisting only of digits/dots, unless 121 * they end in a dot. 122 */ 123 if (isdigit(name[0])) 124 for (cp = name;; ++cp) { 125 if (!*cp) { 126 if (*--cp == '.') 127 break; 128 /* 129 * All-numeric, no dot at the end. 130 * Fake up a hostent as if we'd actually 131 * done a lookup. 132 */ 133 if (!inet_aton(name, &host_addr)) { 134 h_errno = HOST_NOT_FOUND; 135 return((struct hostent *) NULL); 136 } 137 host.h_name = (char *)name; 138 host.h_aliases = host_aliases; 139 host_aliases[0] = NULL; 140 host.h_addrtype = AF_INET; 141 host.h_length = sizeof(u_int32_t); 142 h_addr_ptrs[0] = (char *)&host_addr; 143 h_addr_ptrs[1] = NULL; 144 host.h_addr_list = h_addr_ptrs; 145 return (&host); 146 } 147 if (!isdigit(*cp) && *cp != '.') 148 break; 149 } 150 151 /* XXX - Force host table lookup. */ 152 return (_gethtbyname(name)); 153 } 154 155 struct hostent * 156 gethostbyaddr(addr, len, type) 157 const char *addr; 158 int len, 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