xref: /illumos-gate/usr/src/lib/libresolv2/common/irs/irp_nw.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * Copyright (c) 1999 by Sun Microsystems, Inc.
3  * All rights reserved.
4  */
5 
6 /*
7  * Portions Copyright (c) 1996,1998 by Internet Software Consortium.
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
14  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
16  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
17  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
18  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20  * SOFTWARE.
21  */
22 
23 #pragma ident	"%Z%%M%	%I%	%E% SMI"
24 
25 #if defined(LIBC_SCCS) && !defined(lint)
26 static const char rcsid[] = "$Id: irp_nw.c,v 8.1 1999/01/18 07:46:54 vixie Exp $";
27 #endif /* LIBC_SCCS and not lint */
28 
29 #if 0
30 
31 #endif
32 
33 /* Imports */
34 
35 #include "port_before.h"
36 
37 #include <syslog.h>
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
43 #include <arpa/nameser.h>
44 
45 #include <errno.h>
46 #include <fcntl.h>
47 #include <resolv.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <syslog.h>
52 
53 #include <irs.h>
54 #include <irp.h>
55 #include <isc/irpmarshall.h>
56 
57 #include <isc/memcluster.h>
58 #include <isc/misc.h>
59 
60 #include "irs_p.h"
61 #include "lcl_p.h"
62 #include "irp_p.h"
63 
64 #include "port_after.h"
65 
66 #define MAXALIASES 35
67 #define MAXADDRSIZE 4
68 
69 struct pvt {
70 	struct irp_p	       *girpdata;
71 	int			warned;
72 	struct nwent		net;
73 };
74 
75 /* Forward */
76 
77 static void		nw_close(struct irs_nw *);
78 static struct nwent *	nw_byname(struct irs_nw *, const char *, int);
79 static struct nwent *	nw_byaddr(struct irs_nw *, void *, int, int);
80 static struct nwent *	nw_next(struct irs_nw *);
81 static void		nw_rewind(struct irs_nw *);
82 static void		nw_minimize(struct irs_nw *);
83 
84 static void		free_nw(struct nwent *nw);
85 
86 
87 /* Public */
88 
89 
90 
91 /*
92  * struct irs_nw * irs_irp_nw(struct irs_acc *this)
93  *
94  */
95 
96 struct irs_nw *
97 irs_irp_nw(struct irs_acc *this) {
98 	struct irs_nw *nw;
99 	struct pvt *pvt;
100 
101 	if (!(pvt = memget(sizeof *pvt))) {
102 		errno = ENOMEM;
103 		return (NULL);
104 	}
105 	memset(pvt, 0, sizeof *pvt);
106 
107 	if (!(nw = memget(sizeof *nw))) {
108 		memput(pvt, sizeof *pvt);
109 		errno = ENOMEM;
110 		return (NULL);
111 	}
112 	memset(nw, 0x0, sizeof *nw);
113 	pvt->girpdata = this->private;
114 
115 	nw->private = pvt;
116 	nw->close = nw_close;
117 	nw->byname = nw_byname;
118 	nw->byaddr = nw_byaddr;
119 	nw->next = nw_next;
120 	nw->rewind = nw_rewind;
121 	nw->minimize = nw_minimize;
122 	return (nw);
123 }
124 
125 /* Methods */
126 
127 
128 
129 /*
130  * void nw_close(struct irs_nw *this)
131  *
132  */
133 
134 static void
135 nw_close(struct irs_nw *this) {
136 	struct pvt *pvt = (struct pvt *)this->private;
137 
138 	nw_minimize(this);
139 
140 	free_nw(&pvt->net);
141 
142 	memput(pvt, sizeof *pvt);
143 	memput(this, sizeof *this);
144 }
145 
146 
147 
148 
149 /*
150  * struct nwent * nw_byaddr(struct irs_nw *this, void *net,
151  * 				int length, int type)
152  *
153  */
154 
155 static struct nwent *
156 nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
157 	struct pvt *pvt = (struct pvt *)this->private;
158 	struct nwent *nw = &pvt->net;
159 	char *body = NULL;
160 	size_t bodylen;
161 	int code;
162 	char paddr[24];			/* bigenough for ip4 w/ cidr spec. */
163 	char text[256];
164 
165 	if (inet_net_ntop(type, net, length, paddr, sizeof paddr) == NULL) {
166 		return (NULL);
167 	}
168 
169 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
170 		return (NULL);
171 	}
172 
173 	if (irs_irp_send_command(pvt->girpdata, "getnetbyaddr %s %s",
174 				 paddr, ADDR_T_STR(type)) != 0)
175 		return (NULL);
176 
177 	if (irs_irp_get_full_response(pvt->girpdata, &code,
178 				      text, sizeof text,
179 				      &body, &bodylen) != 0) {
180 		return (NULL);
181 	}
182 
183 	if (code == IRPD_GETNET_OK) {
184 		free_nw(nw);
185 		if (irp_unmarshall_nw(nw, body) != 0) {
186 			nw = NULL;
187 		}
188 	} else {
189 		nw = NULL;
190 	}
191 
192 	if (body != NULL) {
193 		memput(body, bodylen);
194 	}
195 
196 	return (nw);
197 }
198 
199 
200 
201 
202 /*
203  * struct nwent * nw_byname(struct irs_nw *this, const char *name, int type)
204  *
205  */
206 
207 static struct nwent *
208 nw_byname(struct irs_nw *this, const char *name, int type) {
209 	struct pvt *pvt = (struct pvt *)this->private;
210 	struct nwent *nw = &pvt->net;
211 	char *body = NULL;
212 	size_t bodylen;
213 	int code;
214 	char text[256];
215 
216 	if (nw->n_name != NULL &&
217 	    strcmp(name, nw->n_name) == 0 &&
218 	    nw->n_addrtype == type) {
219 		return (nw);
220 	}
221 
222 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
223 		return (NULL);
224 	}
225 
226 	if (irs_irp_send_command(pvt->girpdata, "getnetbyname %s", name) != 0)
227 		return (NULL);
228 
229 	if (irs_irp_get_full_response(pvt->girpdata, &code,
230 				      text, sizeof text,
231 				      &body, &bodylen) != 0) {
232 		return (NULL);
233 	}
234 
235 	if (code == IRPD_GETNET_OK) {
236 		free_nw(nw);
237 		if (irp_unmarshall_nw(nw, body) != 0) {
238 			nw = NULL;
239 		}
240 	} else {
241 		nw = NULL;
242 	}
243 
244 	if (body != NULL) {
245 		memput(body, bodylen);
246 	}
247 
248 	return (nw);
249 }
250 
251 
252 
253 
254 /*
255  * void nw_rewind(struct irs_nw *this)
256  *
257  */
258 
259 static void
260 nw_rewind(struct irs_nw *this) {
261 	struct pvt *pvt = (struct pvt *)this->private;
262 	char text[256];
263 	int code;
264 
265 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
266 		return;
267 	}
268 
269 	if (irs_irp_send_command(pvt->girpdata, "setnetent") != 0) {
270 		return;
271 	}
272 
273 	code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
274 	if (code != IRPD_GETNET_SETOK) {
275 		if (irp_log_errors) {
276 			syslog(LOG_WARNING, "setnetent failed: %s", text);
277 		}
278 	}
279 
280 	return;
281 }
282 
283 
284 
285 
286 
287 
288 /*
289  * struct nwent * nw_next(struct irs_nw *this)
290  *
291  * Notes:
292  *
293  * 	Prepares the cache if necessary and returns the first, or
294  * 	next item from it.
295  */
296 
297 static struct nwent *
298 nw_next(struct irs_nw *this) {
299 	struct pvt *pvt = (struct pvt *)this->private;
300 	struct nwent *nw = &pvt->net;
301 	char *body;
302 	size_t bodylen;
303 	int code;
304 	char text[256];
305 
306 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
307 		return (NULL);
308 	}
309 
310 	if (irs_irp_send_command(pvt->girpdata, "getnetent") != 0) {
311 		return (NULL);
312 	}
313 
314 	if (irs_irp_get_full_response(pvt->girpdata, &code,
315 				      text, sizeof text,
316 				      &body, &bodylen) != 0) {
317 		return (NULL);
318 	}
319 
320 	if (code == IRPD_GETNET_OK) {
321 		free_nw(nw);
322 		if (irp_unmarshall_nw(nw, body) != 0) {
323 			nw = NULL;
324 		}
325 	} else {
326 		nw = NULL;
327 	}
328 
329 	return (nw);
330 }
331 
332 
333 
334 
335 
336 
337 /*
338  * void nw_minimize(struct irs_nw *this)
339  *
340  */
341 
342 static void
343 nw_minimize(struct irs_nw *this) {
344 	struct pvt *pvt = (struct pvt *)this->private;
345 
346 	irs_irp_disconnect(pvt->girpdata);
347 }
348 
349 
350 
351 
352 /* private. */
353 
354 
355 
356 /*
357  * static void free_passwd(struct passwd *pw);
358  *
359  *	deallocate all the memory irp_unmarshall_pw allocated.
360  *
361  */
362 
363 static void
364 free_nw(struct nwent *nw) {
365 	char **p;
366 
367 	if (nw == NULL)
368 		return;
369 
370 	if (nw->n_name != NULL)
371 		free(nw->n_name);
372 
373 	if (nw->n_aliases != NULL) {
374 		for (p = nw->n_aliases ; *p != NULL ; p++) {
375 			free(*p);
376 		}
377 		free(nw->n_aliases);
378 	}
379 
380 	if (nw->n_addr != NULL)
381 		free(nw->n_addr);
382 }
383