gethost.c revision 1.11 1 1.11 christos /* $NetBSD: gethost.c,v 1.11 2013/08/27 09:53:33 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.1 gwr extern 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