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