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