xref: /freebsd/lib/libc/net/getnetbyht.c (revision acd3428b7d3e94cef0e1881c868cb4b131d4ff41)
1 /*
2  * Copyright (c) 1983, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 /* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
35  *	Dep. Matematica Universidade de Coimbra, Portugal, Europe
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.
40  *
41  * from getnetent.c	1.1 (Coimbra) 93/06/02
42  */
43 
44 #if defined(LIBC_SCCS) && !defined(lint)
45 static char sccsid[] = "@(#)getnetent.c	8.1 (Berkeley) 6/4/93";
46 static char orig_rcsid[] = "From: Id: getnetent.c,v 8.4 1997/06/01 20:34:37 vixie Exp";
47 #endif /* LIBC_SCCS and not lint */
48 #include <sys/cdefs.h>
49 __FBSDID("$FreeBSD$");
50 
51 #include <sys/types.h>
52 #include <sys/socket.h>
53 #include <netinet/in.h>
54 #include <arpa/inet.h>
55 #include <arpa/nameser.h>
56 #include <netdb.h>
57 #include <resolv.h>
58 #include <stdio.h>
59 #include <string.h>
60 #include <stdarg.h>
61 #include <nsswitch.h>
62 #include "netdb_private.h"
63 
64 void
65 _setnethtent(int f, struct netent_data *ned)
66 {
67 
68 	if (ned->netf == NULL)
69 		ned->netf = fopen(_PATH_NETWORKS, "r");
70 	else
71 		rewind(ned->netf);
72 	ned->stayopen |= f;
73 }
74 
75 void
76 _endnethtent(struct netent_data *ned)
77 {
78 
79 	if (ned->netf) {
80 		fclose(ned->netf);
81 		ned->netf = NULL;
82 	}
83 	ned->stayopen = 0;
84 }
85 
86 static int
87 getnetent_p(struct netent *ne, struct netent_data *ned)
88 {
89 	char *p, *bp, *ep;
90 	char *cp, **q;
91 	int len;
92 	char line[BUFSIZ + 1];
93 
94 	if (ned->netf == NULL &&
95 	    (ned->netf = fopen(_PATH_NETWORKS, "r")) == NULL)
96 		return (-1);
97 again:
98 	p = fgets(line, sizeof line, ned->netf);
99 	if (p == NULL)
100 		return (-1);
101 	if (*p == '#')
102 		goto again;
103 	cp = strpbrk(p, "#\n");
104 	if (cp != NULL)
105 		*cp = '\0';
106 	bp = ned->netbuf;
107 	ep = ned->netbuf + sizeof ned->netbuf;
108 	ne->n_name = bp;
109 	cp = strpbrk(p, " \t");
110 	if (cp == NULL)
111 		goto again;
112 	*cp++ = '\0';
113 	len = strlen(p) + 1;
114 	if (ep - bp < len) {
115 		RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
116 		return (-1);
117 	}
118 	strlcpy(bp, p, ep - bp);
119 	bp += len;
120 	while (*cp == ' ' || *cp == '\t')
121 		cp++;
122 	p = strpbrk(cp, " \t");
123 	if (p != NULL)
124 		*p++ = '\0';
125 	ne->n_net = inet_network(cp);
126 	ne->n_addrtype = AF_INET;
127 	q = ne->n_aliases = ned->net_aliases;
128 	if (p != NULL) {
129 		cp = p;
130 		while (cp && *cp) {
131 			if (*cp == ' ' || *cp == '\t') {
132 				cp++;
133 				continue;
134 			}
135 			if (q >= &ned->net_aliases[_MAXALIASES - 1])
136 				break;
137 			p = strpbrk(cp, " \t");
138 			if (p != NULL)
139 				*p++ = '\0';
140 			len = strlen(cp) + 1;
141 			if (ep - bp < len)
142 				break;
143 			strlcpy(bp, cp, ep - bp);
144 			*q++ = bp;
145 			bp += len;
146 			cp = p;
147 		}
148 	}
149 	*q = NULL;
150 	return (0);
151 }
152 
153 int
154 getnetent_r(struct netent *nptr, char *buffer, size_t buflen,
155     struct netent **result, int *h_errnop)
156 {
157 	struct netent_data *ned;
158 	struct netent ne;
159 	res_state statp;
160 
161 	statp = __res_state();
162 	if ((ned = __netent_data_init()) == NULL) {
163 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
164 		*h_errnop = statp->res_h_errno;
165 		return (-1);
166 	}
167 	if (getnetent_p(&ne, ned) != 0)
168 		return (-1);
169 	if (__copy_netent(&ne, nptr, buffer, buflen) != 0)
170 		return (-1);
171 	*result = nptr;
172 	return (0);
173 }
174 
175 struct netent *
176 getnetent(void)
177 {
178 	struct netdata *nd;
179 	struct netent *rval;
180 	int ret_h_errno;
181 
182 	if ((nd = __netdata_init()) == NULL)
183 		return (NULL);
184 	if (getnetent_r(&nd->net, nd->data, sizeof(nd->data), &rval,
185 	    &ret_h_errno) != 0)
186 		return (NULL);
187 	return (rval);
188 }
189 
190 int
191 _ht_getnetbyname(void *rval, void *cb_data, va_list ap)
192 {
193 	const char *name;
194 	char *buffer;
195 	size_t buflen;
196 	int *errnop, *h_errnop;
197 	struct netent *nptr, ne;
198 	struct netent_data *ned;
199 	char **cp;
200 	res_state statp;
201 	int error;
202 
203 	name = va_arg(ap, const char *);
204 	nptr = va_arg(ap, struct netent *);
205 	buffer = va_arg(ap, char *);
206 	buflen = va_arg(ap, size_t);
207 	errnop = va_arg(ap, int *);
208 	h_errnop = va_arg(ap, int *);
209 
210 	statp = __res_state();
211 	if ((ned = __netent_data_init()) == NULL) {
212 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
213 		*h_errnop = statp->res_h_errno;
214 		return (NS_UNAVAIL);
215 	}
216 
217 	_setnethtent(ned->stayopen, ned);
218 	while ((error = getnetent_p(&ne, ned)) == 0) {
219 		if (strcasecmp(ne.n_name, name) == 0)
220 			break;
221 		for (cp = ne.n_aliases; *cp != 0; cp++)
222 			if (strcasecmp(*cp, name) == 0)
223 				goto found;
224 	}
225 found:
226 	if (!ned->stayopen)
227 		_endnethtent(ned);
228 	if (error != 0) {
229 		*h_errnop = statp->res_h_errno;
230 		return (NS_NOTFOUND);
231 	}
232 	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
233 		*h_errnop = statp->res_h_errno;
234 		return (NS_NOTFOUND);
235 	}
236 	*((struct netent **)rval) = nptr;
237 	return (NS_SUCCESS);
238 }
239 
240 int
241 _ht_getnetbyaddr(void *rval, void *cb_data, va_list ap)
242 {
243 	uint32_t net;
244 	int type;
245 	char *buffer;
246 	size_t buflen;
247 	int *errnop, *h_errnop;
248 	struct netent *nptr, ne;
249 	struct netent_data *ned;
250 	res_state statp;
251 	int error;
252 
253 	net = va_arg(ap, uint32_t);
254 	type = va_arg(ap, int);
255 	nptr = va_arg(ap, struct netent *);
256 	buffer = va_arg(ap, char *);
257 	buflen = va_arg(ap, size_t);
258 	errnop = va_arg(ap, int *);
259 	h_errnop = va_arg(ap, int *);
260 
261 	statp = __res_state();
262 	if ((ned = __netent_data_init()) == NULL) {
263 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
264 		*h_errnop = statp->res_h_errno;
265 		return (NS_UNAVAIL);
266 	}
267 
268 	_setnethtent(ned->stayopen, ned);
269 	while ((error = getnetent_p(&ne, ned)) == 0)
270 		if (ne.n_addrtype == type && ne.n_net == net)
271 			break;
272 	if (!ned->stayopen)
273 		_endnethtent(ned);
274 	if (error != 0) {
275 		*h_errnop = statp->res_h_errno;
276 		return (NS_NOTFOUND);
277 	}
278 	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
279 		*h_errnop = statp->res_h_errno;
280 		return (NS_NOTFOUND);
281 	}
282 	*((struct netent **)rval) = nptr;
283 	return (NS_SUCCESS);
284 }
285