rpcb_svc_4.c revision 1.5 1 1.5 christos /* $NetBSD: rpcb_svc_4.c,v 1.5 2006/05/25 02:33:16 christos Exp $ */
2 1.1 fvdl
3 1.1 fvdl /*
4 1.1 fvdl * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 1.1 fvdl * unrestricted use provided that this legend is included on all tape
6 1.1 fvdl * media and as a part of the software program in whole or part. Users
7 1.1 fvdl * may copy or modify Sun RPC without charge, but are not authorized
8 1.1 fvdl * to license or distribute it to anyone else except as part of a product or
9 1.1 fvdl * program developed by the user.
10 1.1 fvdl *
11 1.1 fvdl * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 1.1 fvdl * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 1.1 fvdl * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 1.1 fvdl *
15 1.1 fvdl * Sun RPC is provided with no support and without any obligation on the
16 1.1 fvdl * part of Sun Microsystems, Inc. to assist in its use, correction,
17 1.1 fvdl * modification or enhancement.
18 1.1 fvdl *
19 1.1 fvdl * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 1.1 fvdl * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 1.1 fvdl * OR ANY PART THEREOF.
22 1.1 fvdl *
23 1.1 fvdl * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 1.1 fvdl * or profits or other special, indirect and consequential damages, even if
25 1.1 fvdl * Sun has been advised of the possibility of such damages.
26 1.1 fvdl *
27 1.1 fvdl * Sun Microsystems, Inc.
28 1.1 fvdl * 2550 Garcia Avenue
29 1.1 fvdl * Mountain View, California 94043
30 1.1 fvdl */
31 1.1 fvdl /*
32 1.1 fvdl * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
33 1.1 fvdl */
34 1.1 fvdl
35 1.1 fvdl /* #ident "@(#)rpcb_svc_4.c 1.8 93/07/05 SMI" */
36 1.1 fvdl
37 1.1 fvdl /*
38 1.1 fvdl * rpcb_svc_4.c
39 1.1 fvdl * The server procedure for the version 4 rpcbind.
40 1.1 fvdl *
41 1.1 fvdl */
42 1.1 fvdl
43 1.1 fvdl #include <sys/types.h>
44 1.1 fvdl #include <sys/stat.h>
45 1.1 fvdl #include <rpc/rpc.h>
46 1.1 fvdl #include <stdio.h>
47 1.1 fvdl #include <unistd.h>
48 1.1 fvdl #include <netconfig.h>
49 1.1 fvdl #include <syslog.h>
50 1.1 fvdl #include <string.h>
51 1.1 fvdl #include <stdlib.h>
52 1.1 fvdl #include "rpcbind.h"
53 1.1 fvdl
54 1.1 fvdl static void *rpcbproc_getaddr_4_local __P((void *, struct svc_req *, SVCXPRT *,
55 1.1 fvdl rpcvers_t));
56 1.1 fvdl static void *rpcbproc_getversaddr_4_local __P((void *, struct svc_req *, SVCXPRT *, rpcvers_t));
57 1.1 fvdl static void *rpcbproc_getaddrlist_4_local
58 1.1 fvdl __P((void *, struct svc_req *, SVCXPRT *, rpcvers_t));
59 1.1 fvdl static void free_rpcb_entry_list __P((rpcb_entry_list_ptr *));
60 1.1 fvdl static void *rpcbproc_dump_4_local __P((void *, struct svc_req *, SVCXPRT *, rpcvers_t));
61 1.1 fvdl
62 1.1 fvdl /*
63 1.1 fvdl * Called by svc_getreqset. There is a separate server handle for
64 1.1 fvdl * every transport that it waits on.
65 1.1 fvdl */
66 1.1 fvdl void
67 1.1 fvdl rpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp)
68 1.1 fvdl {
69 1.1 fvdl union {
70 1.1 fvdl rpcb rpcbproc_set_4_arg;
71 1.1 fvdl rpcb rpcbproc_unset_4_arg;
72 1.1 fvdl rpcb rpcbproc_getaddr_4_local_arg;
73 1.1 fvdl char *rpcbproc_uaddr2taddr_4_arg;
74 1.1 fvdl struct netbuf rpcbproc_taddr2uaddr_4_arg;
75 1.1 fvdl } argument;
76 1.1 fvdl char *result;
77 1.1 fvdl xdrproc_t xdr_argument, xdr_result;
78 1.1 fvdl void *(*local) __P((void *, struct svc_req *, SVCXPRT *, rpcvers_t));
79 1.1 fvdl
80 1.1 fvdl rpcbs_procinfo(RPCBVERS_4_STAT, rqstp->rq_proc);
81 1.1 fvdl
82 1.1 fvdl switch (rqstp->rq_proc) {
83 1.1 fvdl case NULLPROC:
84 1.1 fvdl /*
85 1.1 fvdl * Null proc call
86 1.1 fvdl */
87 1.1 fvdl #ifdef RPCBIND_DEBUG
88 1.1 fvdl if (debugging)
89 1.1 fvdl fprintf(stderr, "RPCBPROC_NULL\n");
90 1.1 fvdl #endif
91 1.1 fvdl check_access(transp, rqstp->rq_proc, NULL, RPCBVERS4);
92 1.1 fvdl (void) svc_sendreply(transp, (xdrproc_t) xdr_void,
93 1.1 fvdl (char *)NULL);
94 1.1 fvdl return;
95 1.1 fvdl
96 1.1 fvdl case RPCBPROC_SET:
97 1.1 fvdl /*
98 1.1 fvdl * Check to see whether the message came from
99 1.1 fvdl * loopback transports (for security reasons)
100 1.1 fvdl */
101 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb;
102 1.1 fvdl xdr_result = (xdrproc_t)xdr_bool;
103 1.1 fvdl local = rpcbproc_set_com;
104 1.1 fvdl break;
105 1.1 fvdl
106 1.1 fvdl case RPCBPROC_UNSET:
107 1.1 fvdl /*
108 1.1 fvdl * Check to see whether the message came from
109 1.1 fvdl * loopback transports (for security reasons)
110 1.1 fvdl */
111 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb;
112 1.1 fvdl xdr_result = (xdrproc_t)xdr_bool;
113 1.1 fvdl local = rpcbproc_unset_com;
114 1.1 fvdl break;
115 1.1 fvdl
116 1.1 fvdl case RPCBPROC_GETADDR:
117 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb;
118 1.1 fvdl xdr_result = (xdrproc_t)xdr_wrapstring;
119 1.1 fvdl local = rpcbproc_getaddr_4_local;
120 1.1 fvdl break;
121 1.1 fvdl
122 1.1 fvdl case RPCBPROC_GETVERSADDR:
123 1.1 fvdl #ifdef RPCBIND_DEBUG
124 1.1 fvdl if (debugging)
125 1.1 fvdl fprintf(stderr, "RPCBPROC_GETVERSADDR\n");
126 1.1 fvdl #endif
127 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb;
128 1.1 fvdl xdr_result = (xdrproc_t)xdr_wrapstring;
129 1.1 fvdl local = rpcbproc_getversaddr_4_local;
130 1.1 fvdl break;
131 1.1 fvdl
132 1.1 fvdl case RPCBPROC_DUMP:
133 1.1 fvdl #ifdef RPCBIND_DEBUG
134 1.1 fvdl if (debugging)
135 1.1 fvdl fprintf(stderr, "RPCBPROC_DUMP\n");
136 1.1 fvdl #endif
137 1.1 fvdl xdr_argument = (xdrproc_t)xdr_void;
138 1.1 fvdl xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
139 1.1 fvdl local = rpcbproc_dump_4_local;
140 1.1 fvdl break;
141 1.1 fvdl
142 1.1 fvdl case RPCBPROC_INDIRECT:
143 1.1 fvdl #ifdef RPCBIND_DEBUG
144 1.1 fvdl if (debugging)
145 1.1 fvdl fprintf(stderr, "RPCBPROC_INDIRECT\n");
146 1.1 fvdl #endif
147 1.1 fvdl rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
148 1.1 fvdl return;
149 1.1 fvdl
150 1.1 fvdl /* case RPCBPROC_CALLIT: */
151 1.1 fvdl case RPCBPROC_BCAST:
152 1.1 fvdl #ifdef RPCBIND_DEBUG
153 1.1 fvdl if (debugging)
154 1.1 fvdl fprintf(stderr, "RPCBPROC_BCAST\n");
155 1.1 fvdl #endif
156 1.1 fvdl rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
157 1.1 fvdl return;
158 1.1 fvdl
159 1.1 fvdl case RPCBPROC_GETTIME:
160 1.1 fvdl #ifdef RPCBIND_DEBUG
161 1.1 fvdl if (debugging)
162 1.1 fvdl fprintf(stderr, "RPCBPROC_GETTIME\n");
163 1.1 fvdl #endif
164 1.1 fvdl xdr_argument = (xdrproc_t)xdr_void;
165 1.1 fvdl xdr_result = (xdrproc_t)xdr_u_long;
166 1.1 fvdl local = rpcbproc_gettime_com;
167 1.1 fvdl break;
168 1.1 fvdl
169 1.1 fvdl case RPCBPROC_UADDR2TADDR:
170 1.1 fvdl #ifdef RPCBIND_DEBUG
171 1.1 fvdl if (debugging)
172 1.1 fvdl fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
173 1.1 fvdl #endif
174 1.1 fvdl xdr_argument = (xdrproc_t)xdr_wrapstring;
175 1.1 fvdl xdr_result = (xdrproc_t)xdr_netbuf;
176 1.1 fvdl local = rpcbproc_uaddr2taddr_com;
177 1.1 fvdl break;
178 1.1 fvdl
179 1.1 fvdl case RPCBPROC_TADDR2UADDR:
180 1.1 fvdl #ifdef RPCBIND_DEBUG
181 1.1 fvdl if (debugging)
182 1.1 fvdl fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
183 1.1 fvdl #endif
184 1.1 fvdl xdr_argument = (xdrproc_t)xdr_netbuf;
185 1.1 fvdl xdr_result = (xdrproc_t)xdr_wrapstring;
186 1.1 fvdl local = rpcbproc_taddr2uaddr_com;
187 1.1 fvdl break;
188 1.1 fvdl
189 1.1 fvdl case RPCBPROC_GETADDRLIST:
190 1.1 fvdl #ifdef RPCBIND_DEBUG
191 1.1 fvdl if (debugging)
192 1.1 fvdl fprintf(stderr, "RPCBPROC_GETADDRLIST\n");
193 1.1 fvdl #endif
194 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb;
195 1.1 fvdl xdr_result = (xdrproc_t)xdr_rpcb_entry_list_ptr;
196 1.1 fvdl local = rpcbproc_getaddrlist_4_local;
197 1.1 fvdl break;
198 1.1 fvdl
199 1.1 fvdl case RPCBPROC_GETSTAT:
200 1.1 fvdl #ifdef RPCBIND_DEBUG
201 1.1 fvdl if (debugging)
202 1.1 fvdl fprintf(stderr, "RPCBPROC_GETSTAT\n");
203 1.1 fvdl #endif
204 1.1 fvdl xdr_argument = (xdrproc_t)xdr_void;
205 1.1 fvdl xdr_result = (xdrproc_t)xdr_rpcb_stat_byvers;
206 1.1 fvdl local = rpcbproc_getstat;
207 1.1 fvdl break;
208 1.1 fvdl
209 1.1 fvdl default:
210 1.1 fvdl svcerr_noproc(transp);
211 1.1 fvdl return;
212 1.1 fvdl }
213 1.1 fvdl memset((char *)&argument, 0, sizeof (argument));
214 1.1 fvdl if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
215 1.1 fvdl (char *)&argument)) {
216 1.1 fvdl svcerr_decode(transp);
217 1.1 fvdl if (debugging)
218 1.1 fvdl (void) fprintf(stderr, "rpcbind: could not decode\n");
219 1.1 fvdl return;
220 1.1 fvdl }
221 1.1 fvdl if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS4)) {
222 1.1 fvdl svcerr_weakauth(transp);
223 1.1 fvdl goto done;
224 1.1 fvdl }
225 1.1 fvdl result = (*local)(&argument, rqstp, transp, RPCBVERS4);
226 1.1 fvdl if (result != NULL && !svc_sendreply(transp, (xdrproc_t) xdr_result,
227 1.1 fvdl result)) {
228 1.1 fvdl svcerr_systemerr(transp);
229 1.1 fvdl if (debugging) {
230 1.1 fvdl (void) fprintf(stderr, "rpcbind: svc_sendreply\n");
231 1.1 fvdl if (doabort) {
232 1.1 fvdl rpcbind_abort();
233 1.1 fvdl }
234 1.1 fvdl }
235 1.1 fvdl }
236 1.1 fvdl done:
237 1.1 fvdl if (!svc_freeargs(transp, (xdrproc_t) xdr_argument,
238 1.1 fvdl (char *)&argument)) {
239 1.1 fvdl if (debugging) {
240 1.1 fvdl (void) fprintf(stderr, "unable to free arguments\n");
241 1.1 fvdl if (doabort) {
242 1.1 fvdl rpcbind_abort();
243 1.1 fvdl }
244 1.1 fvdl }
245 1.1 fvdl }
246 1.1 fvdl return;
247 1.1 fvdl }
248 1.1 fvdl
249 1.1 fvdl /*
250 1.1 fvdl * Lookup the mapping for a program, version and return its
251 1.1 fvdl * address. Assuming that the caller wants the address of the
252 1.1 fvdl * server running on the transport on which the request came.
253 1.1 fvdl * Even if a service with a different version number is available,
254 1.1 fvdl * it will return that address. The client should check with an
255 1.1 fvdl * clnt_call to verify whether the service is the one that is desired.
256 1.1 fvdl * We also try to resolve the universal address in terms of
257 1.1 fvdl * address of the caller.
258 1.1 fvdl */
259 1.1 fvdl /* ARGSUSED */
260 1.1 fvdl static void *
261 1.1 fvdl rpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
262 1.1 fvdl rpcvers_t rpcbversnum)
263 1.1 fvdl {
264 1.1 fvdl RPCB *regp = (RPCB *)arg;
265 1.1 fvdl #ifdef RPCBIND_DEBUG
266 1.1 fvdl if (debugging) {
267 1.1 fvdl char *uaddr;
268 1.1 fvdl
269 1.1 fvdl uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
270 1.1 fvdl svc_getrpccaller(transp));
271 1.1 fvdl fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
272 1.1 fvdl (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
273 1.1 fvdl regp->r_netid, uaddr);
274 1.1 fvdl free(uaddr);
275 1.1 fvdl }
276 1.1 fvdl #endif
277 1.1 fvdl return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
278 1.1 fvdl RPCB_ALLVERS));
279 1.1 fvdl }
280 1.1 fvdl
281 1.1 fvdl /*
282 1.1 fvdl * Lookup the mapping for a program, version and return its
283 1.1 fvdl * address. Assuming that the caller wants the address of the
284 1.1 fvdl * server running on the transport on which the request came.
285 1.1 fvdl *
286 1.1 fvdl * We also try to resolve the universal address in terms of
287 1.1 fvdl * address of the caller.
288 1.1 fvdl */
289 1.1 fvdl /* ARGSUSED */
290 1.1 fvdl static void *
291 1.1 fvdl rpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
292 1.1 fvdl rpcvers_t versnum)
293 1.1 fvdl {
294 1.1 fvdl RPCB *regp = (RPCB *)arg;
295 1.1 fvdl #ifdef RPCBIND_DEBUG
296 1.1 fvdl if (debugging) {
297 1.1 fvdl char *uaddr;
298 1.1 fvdl
299 1.1 fvdl uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
300 1.1 fvdl svc_getrpccaller(transp));
301 1.1 fvdl fprintf(stderr, "RPCB_GETVERSADDR rqst for (%lu, %lu, %s)"
302 1.1 fvdl " from %s : ",
303 1.1 fvdl (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
304 1.1 fvdl regp->r_netid, uaddr);
305 1.1 fvdl free(uaddr);
306 1.1 fvdl }
307 1.1 fvdl #endif
308 1.1 fvdl return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
309 1.1 fvdl RPCB_ONEVERS));
310 1.1 fvdl }
311 1.1 fvdl
312 1.1 fvdl /*
313 1.1 fvdl * Lookup the mapping for a program, version and return the
314 1.1 fvdl * addresses for all transports in the current transport family.
315 1.1 fvdl * We return a merged address.
316 1.1 fvdl */
317 1.1 fvdl /* ARGSUSED */
318 1.1 fvdl static void *
319 1.1 fvdl rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
320 1.1 fvdl rpcvers_t versnum)
321 1.1 fvdl {
322 1.1 fvdl RPCB *regp = (RPCB *)arg;
323 1.1 fvdl static rpcb_entry_list_ptr rlist;
324 1.1 fvdl register rpcblist_ptr rbl;
325 1.3 lukem rpcb_entry_list_ptr rp, tail = NULL;
326 1.1 fvdl rpcprog_t prog;
327 1.1 fvdl rpcvers_t vers;
328 1.1 fvdl rpcb_entry *a;
329 1.1 fvdl struct netconfig *nconf;
330 1.1 fvdl struct netconfig *reg_nconf;
331 1.1 fvdl char *saddr, *maddr = NULL;
332 1.1 fvdl
333 1.1 fvdl free_rpcb_entry_list(&rlist);
334 1.1 fvdl prog = regp->r_prog;
335 1.1 fvdl vers = regp->r_vers;
336 1.1 fvdl reg_nconf = rpcbind_get_conf(transp->xp_netid);
337 1.1 fvdl if (reg_nconf == NULL)
338 1.1 fvdl return (NULL);
339 1.1 fvdl if (*(regp->r_addr) != '\0') {
340 1.1 fvdl saddr = regp->r_addr;
341 1.1 fvdl } else {
342 1.1 fvdl saddr = NULL;
343 1.1 fvdl }
344 1.1 fvdl #ifdef RPCBIND_DEBUG
345 1.1 fvdl if (debugging) {
346 1.1 fvdl fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n",
347 1.1 fvdl regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly);
348 1.1 fvdl }
349 1.1 fvdl #endif
350 1.1 fvdl for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) {
351 1.1 fvdl if ((rbl->rpcb_map.r_prog == prog) &&
352 1.1 fvdl (rbl->rpcb_map.r_vers == vers)) {
353 1.1 fvdl nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid);
354 1.1 fvdl if (nconf == NULL)
355 1.1 fvdl goto fail;
356 1.1 fvdl if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly)
357 1.1 fvdl != 0) {
358 1.1 fvdl continue; /* not same proto family */
359 1.1 fvdl }
360 1.1 fvdl #ifdef RPCBIND_DEBUG
361 1.1 fvdl if (debugging)
362 1.2 fvdl fprintf(stderr, "\tmerge with: %s\n", rbl->rpcb_map.r_addr);
363 1.1 fvdl #endif
364 1.1 fvdl if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid,
365 1.1 fvdl rbl->rpcb_map.r_addr, saddr)) == NULL) {
366 1.1 fvdl #ifdef RPCBIND_DEBUG
367 1.1 fvdl if (debugging)
368 1.1 fvdl fprintf(stderr, " FAILED\n");
369 1.1 fvdl #endif
370 1.1 fvdl continue;
371 1.1 fvdl } else if (!maddr[0]) {
372 1.1 fvdl #ifdef RPCBIND_DEBUG
373 1.1 fvdl if (debugging)
374 1.1 fvdl fprintf(stderr, " SUCCEEDED, but port died - maddr: nullstring\n");
375 1.1 fvdl #endif
376 1.1 fvdl /* The server died. Unset this combination */
377 1.1 fvdl delete_prog(regp->r_prog);
378 1.4 christos free(maddr);
379 1.1 fvdl continue;
380 1.1 fvdl }
381 1.1 fvdl #ifdef RPCBIND_DEBUG
382 1.1 fvdl if (debugging)
383 1.1 fvdl fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr);
384 1.1 fvdl #endif
385 1.1 fvdl /*
386 1.1 fvdl * Add it to rlist.
387 1.1 fvdl */
388 1.1 fvdl rp = (rpcb_entry_list_ptr)
389 1.1 fvdl malloc((u_int)sizeof (rpcb_entry_list));
390 1.4 christos if (rp == NULL) {
391 1.4 christos free(maddr);
392 1.1 fvdl goto fail;
393 1.4 christos }
394 1.1 fvdl a = &rp->rpcb_entry_map;
395 1.1 fvdl a->r_maddr = maddr;
396 1.1 fvdl a->r_nc_netid = nconf->nc_netid;
397 1.1 fvdl a->r_nc_semantics = nconf->nc_semantics;
398 1.1 fvdl a->r_nc_protofmly = nconf->nc_protofmly;
399 1.1 fvdl a->r_nc_proto = nconf->nc_proto;
400 1.1 fvdl rp->rpcb_entry_next = NULL;
401 1.1 fvdl if (rlist == NULL) {
402 1.1 fvdl rlist = rp;
403 1.1 fvdl tail = rp;
404 1.5 christos } else if (tail) {
405 1.1 fvdl tail->rpcb_entry_next = rp;
406 1.1 fvdl tail = rp;
407 1.1 fvdl }
408 1.1 fvdl rp = NULL;
409 1.1 fvdl }
410 1.1 fvdl }
411 1.1 fvdl #ifdef RPCBIND_DEBUG
412 1.1 fvdl if (debugging) {
413 1.1 fvdl for (rp = rlist; rp; rp = rp->rpcb_entry_next) {
414 1.1 fvdl fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr,
415 1.1 fvdl rp->rpcb_entry_map.r_nc_proto);
416 1.1 fvdl }
417 1.1 fvdl }
418 1.1 fvdl #endif
419 1.1 fvdl /*
420 1.1 fvdl * XXX: getaddrlist info is also being stuffed into getaddr.
421 1.1 fvdl * Perhaps wrong, but better than it not getting counted at all.
422 1.1 fvdl */
423 1.1 fvdl rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr);
424 1.1 fvdl return (void *)&rlist;
425 1.1 fvdl
426 1.1 fvdl fail: free_rpcb_entry_list(&rlist);
427 1.1 fvdl return (NULL);
428 1.1 fvdl }
429 1.1 fvdl
430 1.1 fvdl /*
431 1.1 fvdl * Free only the allocated structure, rest is all a pointer to some
432 1.1 fvdl * other data somewhere else.
433 1.1 fvdl */
434 1.1 fvdl static void
435 1.1 fvdl free_rpcb_entry_list(rpcb_entry_list_ptr *rlistp)
436 1.1 fvdl {
437 1.1 fvdl register rpcb_entry_list_ptr rbl, tmp;
438 1.1 fvdl
439 1.1 fvdl for (rbl = *rlistp; rbl != NULL; ) {
440 1.1 fvdl tmp = rbl;
441 1.1 fvdl rbl = rbl->rpcb_entry_next;
442 1.1 fvdl free((char *)tmp->rpcb_entry_map.r_maddr);
443 1.1 fvdl free((char *)tmp);
444 1.1 fvdl }
445 1.1 fvdl *rlistp = NULL;
446 1.1 fvdl }
447 1.1 fvdl
448 1.1 fvdl /* ARGSUSED */
449 1.1 fvdl static void *
450 1.1 fvdl rpcbproc_dump_4_local(void *arg, struct svc_req *req, SVCXPRT *xprt,
451 1.1 fvdl rpcvers_t versnum)
452 1.1 fvdl {
453 1.1 fvdl return ((void *)&list_rbl);
454 1.1 fvdl }
455