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