2 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (c) 1996,1999 by Internet Software Consortium.
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.
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.
18 #if defined(LIBC_SCCS) && !defined(lint)
19 static const char rcsid
[] = "$Id: nis_nw.c,v 1.4 2005/04/27 04:56:33 sra Exp $";
20 #endif /* LIBC_SCCS and not lint */
24 #include "port_before.h"
27 static int __bind_irs_nis_unneeded
;
30 #include <sys/types.h>
31 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <arpa/nameser.h>
37 #undef T_NULL /* Silence re-definition warning of T_NULL. */
41 #include <rpcsvc/yp_prot.h>
42 #include <rpcsvc/ypclnt.h>
50 #include <isc/memcluster.h>
53 #include "port_after.h"
74 char * aliases
[MAXALIASES
+ 1];
75 u_char addr
[MAXADDRSIZE
];
77 struct __res_state
* res
;
78 void (*free_res
)(void *);
81 enum do_what
{ do_none
= 0x0, do_key
= 0x1, do_val
= 0x2, do_all
= 0x3 };
83 static /*const*/ char networks_byname
[] = "networks.byname";
84 static /*const*/ char networks_byaddr
[] = "networks.byaddr";
88 static void nw_close(struct irs_nw
*);
89 static struct nwent
* nw_byname(struct irs_nw
*, const char *, int);
90 static struct nwent
* nw_byaddr(struct irs_nw
*, void *, int, int);
91 static struct nwent
* nw_next(struct irs_nw
*);
92 static void nw_rewind(struct irs_nw
*);
93 static void nw_minimize(struct irs_nw
*);
94 static struct __res_state
* nw_res_get(struct irs_nw
*this);
95 static void nw_res_set(struct irs_nw
*this,
96 struct __res_state
*res
,
97 void (*free_res
)(void *));
99 static struct nwent
* makenwent(struct irs_nw
*this);
100 static void nisfree(struct pvt
*, enum do_what
);
101 static int init(struct irs_nw
*this);
106 irs_nis_nw(struct irs_acc
*this) {
110 if (!(pvt
= memget(sizeof *pvt
))) {
114 memset(pvt
, 0, sizeof *pvt
);
115 if (!(nw
= memget(sizeof *nw
))) {
116 memput(pvt
, sizeof *pvt
);
120 memset(nw
, 0x5e, sizeof *nw
);
122 pvt
->nis_domain
= ((struct nis_p
*)this->private)->domain
;
124 nw
->close
= nw_close
;
125 nw
->byname
= nw_byname
;
126 nw
->byaddr
= nw_byaddr
;
128 nw
->rewind
= nw_rewind
;
129 nw
->minimize
= nw_minimize
;
130 nw
->res_get
= nw_res_get
;
131 nw
->res_set
= nw_res_set
;
138 nw_close(struct irs_nw
*this) {
139 struct pvt
*pvt
= (struct pvt
*)this->private;
142 if (pvt
->res
&& pvt
->free_res
)
143 (*pvt
->free_res
)(pvt
->res
);
146 memput(pvt
, sizeof *pvt
);
147 memput(this, sizeof *this);
150 static struct nwent
*
151 nw_byaddr(struct irs_nw
*this, void *net
, int length
, int af
) {
152 struct pvt
*pvt
= (struct pvt
*)this->private;
153 char tmp
[sizeof "255.255.255.255/32"], *t
;
156 if (init(this) == -1)
160 RES_SET_H_ERRNO(pvt
->res
, NETDB_INTERNAL
);
161 errno
= EAFNOSUPPORT
;
164 nisfree(pvt
, do_val
);
165 /* Try it with /CIDR first. */
166 if (inet_net_ntop(AF_INET
, net
, length
, tmp
, sizeof tmp
) == NULL
) {
167 RES_SET_H_ERRNO(pvt
->res
, NETDB_INTERNAL
);
170 r
= yp_match(pvt
->nis_domain
, networks_byaddr
, tmp
, strlen(tmp
),
171 &pvt
->curval_data
, &pvt
->curval_len
);
173 /* Give it a shot without the /CIDR. */
174 if ((t
= strchr(tmp
, '/')) != NULL
) {
176 r
= yp_match(pvt
->nis_domain
, networks_byaddr
,
178 &pvt
->curval_data
, &pvt
->curval_len
);
181 RES_SET_H_ERRNO(pvt
->res
, HOST_NOT_FOUND
);
185 return (makenwent(this));
188 static struct nwent
*
189 nw_byname(struct irs_nw
*this, const char *name
, int af
) {
190 struct pvt
*pvt
= (struct pvt
*)this->private;
194 if (init(this) == -1)
198 RES_SET_H_ERRNO(pvt
->res
, NETDB_INTERNAL
);
199 errno
= EAFNOSUPPORT
;
202 nisfree(pvt
, do_val
);
204 r
= yp_match(pvt
->nis_domain
, networks_byname
, tmp
,
205 strlen(tmp
), &pvt
->curval_data
, &pvt
->curval_len
);
207 RES_SET_H_ERRNO(pvt
->res
, HOST_NOT_FOUND
);
210 return (makenwent(this));
214 nw_rewind(struct irs_nw
*this) {
215 struct pvt
*pvt
= (struct pvt
*)this->private;
220 static struct nwent
*
221 nw_next(struct irs_nw
*this) {
222 struct pvt
*pvt
= (struct pvt
*)this->private;
226 if (init(this) == -1)
230 if (pvt
->needrewind
) {
231 nisfree(pvt
, do_all
);
232 r
= yp_first(pvt
->nis_domain
, networks_byaddr
,
233 &pvt
->curkey_data
, &pvt
->curkey_len
,
234 &pvt
->curval_data
, &pvt
->curval_len
);
240 nisfree(pvt
, do_val
);
241 r
= yp_next(pvt
->nis_domain
, networks_byaddr
,
242 pvt
->curkey_data
, pvt
->curkey_len
,
243 &newkey_data
, &newkey_len
,
244 &pvt
->curval_data
, &pvt
->curval_len
);
245 nisfree(pvt
, do_key
);
246 pvt
->curkey_data
= newkey_data
;
247 pvt
->curkey_len
= newkey_len
;
250 RES_SET_H_ERRNO(pvt
->res
, HOST_NOT_FOUND
);
253 rval
= makenwent(this);
254 } while (rval
== NULL
);
259 nw_minimize(struct irs_nw
*this) {
260 struct pvt
*pvt
= (struct pvt
*)this->private;
263 res_nclose(pvt
->res
);
266 static struct __res_state
*
267 nw_res_get(struct irs_nw
*this) {
268 struct pvt
*pvt
= (struct pvt
*)this->private;
271 struct __res_state
*res
;
272 res
= (struct __res_state
*)malloc(sizeof *res
);
277 memset(res
, 0, sizeof *res
);
278 nw_res_set(this, res
, free
);
285 nw_res_set(struct irs_nw
*this, struct __res_state
*res
,
286 void (*free_res
)(void *)) {
287 struct pvt
*pvt
= (struct pvt
*)this->private;
289 if (pvt
->res
&& pvt
->free_res
) {
290 res_nclose(pvt
->res
);
291 (*pvt
->free_res
)(pvt
->res
);
295 pvt
->free_res
= free_res
;
300 static struct nwent
*
301 makenwent(struct irs_nw
*this) {
302 struct pvt
*pvt
= (struct pvt
*)this->private;
303 static const char spaces
[] = " \t";
308 pvt
->nwbuf
= pvt
->curval_data
;
309 pvt
->curval_data
= NULL
;
311 if ((cp
= strpbrk(pvt
->nwbuf
, "#\n")) != NULL
)
316 pvt
->nwent
.n_name
= cp
;
317 cp
+= strcspn(cp
, spaces
);
321 cp
+= strspn(cp
, spaces
);
324 pvt
->nwent
.n_addrtype
= AF_INET
;
325 t
= cp
+ strcspn(cp
, spaces
);
328 pvt
->nwent
.n_length
= inet_net_pton(AF_INET
, cp
,
329 pvt
->addr
, sizeof pvt
->addr
);
330 if (pvt
->nwent
.n_length
< 0)
332 pvt
->nwent
.n_addr
= pvt
->addr
;
336 ap
= pvt
->nwent
.n_aliases
= pvt
->aliases
;
338 if (ap
>= &pvt
->aliases
[MAXALIASES
])
341 cp
+= strcspn(cp
, spaces
);
345 cp
+= strspn(cp
, spaces
);
349 return (&pvt
->nwent
);
360 nisfree(struct pvt
*pvt
, enum do_what do_what
) {
361 if ((do_what
& do_key
) && pvt
->curkey_data
) {
362 free(pvt
->curkey_data
);
363 pvt
->curkey_data
= NULL
;
365 if ((do_what
& do_val
) && pvt
->curval_data
) {
366 free(pvt
->curval_data
);
367 pvt
->curval_data
= NULL
;
372 init(struct irs_nw
*this) {
373 struct pvt
*pvt
= (struct pvt
*)this->private;
375 if (!pvt
->res
&& !nw_res_get(this))
377 if (((pvt
->res
->options
& RES_INIT
) == 0) &&
378 res_ninit(pvt
->res
) == -1)
383 #endif /*WANT_IRS_NIS*/