rpcb_svc_4.c revision 1.7 1 1.7 plunky /* $NetBSD: rpcb_svc_4.c,v 1.7 2011/08/31 16:25:00 plunky 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.6 christos static void *rpcbproc_getaddr_4_local(void *, struct svc_req *, SVCXPRT *,
55 1.6 christos rpcvers_t);
56 1.6 christos static void *rpcbproc_getversaddr_4_local(void *, struct svc_req *, SVCXPRT *,
57 1.6 christos rpcvers_t);
58 1.6 christos static void *rpcbproc_getaddrlist_4_local(void *, struct svc_req *, SVCXPRT *,
59 1.6 christos rpcvers_t);
60 1.6 christos static void free_rpcb_entry_list(rpcb_entry_list_ptr *);
61 1.6 christos static void *rpcbproc_dump_4_local(void *, struct svc_req *, SVCXPRT *,
62 1.6 christos rpcvers_t);
63 1.1 fvdl
64 1.1 fvdl /*
65 1.1 fvdl * Called by svc_getreqset. There is a separate server handle for
66 1.1 fvdl * every transport that it waits on.
67 1.1 fvdl */
68 1.1 fvdl void
69 1.1 fvdl rpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp)
70 1.1 fvdl {
71 1.1 fvdl union {
72 1.1 fvdl rpcb rpcbproc_set_4_arg;
73 1.1 fvdl rpcb rpcbproc_unset_4_arg;
74 1.1 fvdl rpcb rpcbproc_getaddr_4_local_arg;
75 1.1 fvdl char *rpcbproc_uaddr2taddr_4_arg;
76 1.1 fvdl struct netbuf rpcbproc_taddr2uaddr_4_arg;
77 1.1 fvdl } argument;
78 1.1 fvdl char *result;
79 1.1 fvdl xdrproc_t xdr_argument, xdr_result;
80 1.6 christos void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
81 1.1 fvdl
82 1.1 fvdl rpcbs_procinfo(RPCBVERS_4_STAT, rqstp->rq_proc);
83 1.1 fvdl
84 1.1 fvdl switch (rqstp->rq_proc) {
85 1.1 fvdl case NULLPROC:
86 1.1 fvdl /*
87 1.1 fvdl * Null proc call
88 1.1 fvdl */
89 1.1 fvdl #ifdef RPCBIND_DEBUG
90 1.1 fvdl if (debugging)
91 1.1 fvdl fprintf(stderr, "RPCBPROC_NULL\n");
92 1.1 fvdl #endif
93 1.1 fvdl check_access(transp, rqstp->rq_proc, NULL, RPCBVERS4);
94 1.7 plunky (void) svc_sendreply(transp, (xdrproc_t) xdr_void, NULL);
95 1.1 fvdl return;
96 1.1 fvdl
97 1.1 fvdl case RPCBPROC_SET:
98 1.1 fvdl /*
99 1.1 fvdl * Check to see whether the message came from
100 1.1 fvdl * loopback transports (for security reasons)
101 1.1 fvdl */
102 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb;
103 1.1 fvdl xdr_result = (xdrproc_t)xdr_bool;
104 1.1 fvdl local = rpcbproc_set_com;
105 1.1 fvdl break;
106 1.1 fvdl
107 1.1 fvdl case RPCBPROC_UNSET:
108 1.1 fvdl /*
109 1.1 fvdl * Check to see whether the message came from
110 1.1 fvdl * loopback transports (for security reasons)
111 1.1 fvdl */
112 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb;
113 1.1 fvdl xdr_result = (xdrproc_t)xdr_bool;
114 1.1 fvdl local = rpcbproc_unset_com;
115 1.1 fvdl break;
116 1.1 fvdl
117 1.1 fvdl case RPCBPROC_GETADDR:
118 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb;
119 1.1 fvdl xdr_result = (xdrproc_t)xdr_wrapstring;
120 1.1 fvdl local = rpcbproc_getaddr_4_local;
121 1.1 fvdl break;
122 1.1 fvdl
123 1.1 fvdl case RPCBPROC_GETVERSADDR:
124 1.1 fvdl #ifdef RPCBIND_DEBUG
125 1.1 fvdl if (debugging)
126 1.1 fvdl fprintf(stderr, "RPCBPROC_GETVERSADDR\n");
127 1.1 fvdl #endif
128 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb;
129 1.1 fvdl xdr_result = (xdrproc_t)xdr_wrapstring;
130 1.1 fvdl local = rpcbproc_getversaddr_4_local;
131 1.1 fvdl break;
132 1.1 fvdl
133 1.1 fvdl case RPCBPROC_DUMP:
134 1.1 fvdl #ifdef RPCBIND_DEBUG
135 1.1 fvdl if (debugging)
136 1.1 fvdl fprintf(stderr, "RPCBPROC_DUMP\n");
137 1.1 fvdl #endif
138 1.1 fvdl xdr_argument = (xdrproc_t)xdr_void;
139 1.1 fvdl xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
140 1.1 fvdl local = rpcbproc_dump_4_local;
141 1.1 fvdl break;
142 1.1 fvdl
143 1.1 fvdl case RPCBPROC_INDIRECT:
144 1.1 fvdl #ifdef RPCBIND_DEBUG
145 1.1 fvdl if (debugging)
146 1.1 fvdl fprintf(stderr, "RPCBPROC_INDIRECT\n");
147 1.1 fvdl #endif
148 1.1 fvdl rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
149 1.1 fvdl return;
150 1.1 fvdl
151 1.1 fvdl /* case RPCBPROC_CALLIT: */
152 1.1 fvdl case RPCBPROC_BCAST:
153 1.1 fvdl #ifdef RPCBIND_DEBUG
154 1.1 fvdl if (debugging)
155 1.1 fvdl fprintf(stderr, "RPCBPROC_BCAST\n");
156 1.1 fvdl #endif
157 1.1 fvdl rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
158 1.1 fvdl return;
159 1.1 fvdl
160 1.1 fvdl case RPCBPROC_GETTIME:
161 1.1 fvdl #ifdef RPCBIND_DEBUG
162 1.1 fvdl if (debugging)
163 1.1 fvdl fprintf(stderr, "RPCBPROC_GETTIME\n");
164 1.1 fvdl #endif
165 1.1 fvdl xdr_argument = (xdrproc_t)xdr_void;
166 1.1 fvdl xdr_result = (xdrproc_t)xdr_u_long;
167 1.1 fvdl local = rpcbproc_gettime_com;
168 1.1 fvdl break;
169 1.1 fvdl
170 1.1 fvdl case RPCBPROC_UADDR2TADDR:
171 1.1 fvdl #ifdef RPCBIND_DEBUG
172 1.1 fvdl if (debugging)
173 1.1 fvdl fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
174 1.1 fvdl #endif
175 1.1 fvdl xdr_argument = (xdrproc_t)xdr_wrapstring;
176 1.1 fvdl xdr_result = (xdrproc_t)xdr_netbuf;
177 1.1 fvdl local = rpcbproc_uaddr2taddr_com;
178 1.1 fvdl break;
179 1.1 fvdl
180 1.1 fvdl case RPCBPROC_TADDR2UADDR:
181 1.1 fvdl #ifdef RPCBIND_DEBUG
182 1.1 fvdl if (debugging)
183 1.1 fvdl fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
184 1.1 fvdl #endif
185 1.1 fvdl xdr_argument = (xdrproc_t)xdr_netbuf;
186 1.1 fvdl xdr_result = (xdrproc_t)xdr_wrapstring;
187 1.1 fvdl local = rpcbproc_taddr2uaddr_com;
188 1.1 fvdl break;
189 1.1 fvdl
190 1.1 fvdl case RPCBPROC_GETADDRLIST:
191 1.1 fvdl #ifdef RPCBIND_DEBUG
192 1.1 fvdl if (debugging)
193 1.1 fvdl fprintf(stderr, "RPCBPROC_GETADDRLIST\n");
194 1.1 fvdl #endif
195 1.1 fvdl xdr_argument = (xdrproc_t)xdr_rpcb;
196 1.1 fvdl xdr_result = (xdrproc_t)xdr_rpcb_entry_list_ptr;
197 1.1 fvdl local = rpcbproc_getaddrlist_4_local;
198 1.1 fvdl break;
199 1.1 fvdl
200 1.1 fvdl case RPCBPROC_GETSTAT:
201 1.1 fvdl #ifdef RPCBIND_DEBUG
202 1.1 fvdl if (debugging)
203 1.1 fvdl fprintf(stderr, "RPCBPROC_GETSTAT\n");
204 1.1 fvdl #endif
205 1.1 fvdl xdr_argument = (xdrproc_t)xdr_void;
206 1.1 fvdl xdr_result = (xdrproc_t)xdr_rpcb_stat_byvers;
207 1.1 fvdl local = rpcbproc_getstat;
208 1.1 fvdl break;
209 1.1 fvdl
210 1.1 fvdl default:
211 1.1 fvdl svcerr_noproc(transp);
212 1.1 fvdl return;
213 1.1 fvdl }
214 1.1 fvdl memset((char *)&argument, 0, sizeof (argument));
215 1.1 fvdl if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
216 1.1 fvdl (char *)&argument)) {
217 1.1 fvdl svcerr_decode(transp);
218 1.1 fvdl if (debugging)
219 1.1 fvdl (void) fprintf(stderr, "rpcbind: could not decode\n");
220 1.1 fvdl return;
221 1.1 fvdl }
222 1.1 fvdl if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS4)) {
223 1.1 fvdl svcerr_weakauth(transp);
224 1.1 fvdl goto done;
225 1.1 fvdl }
226 1.1 fvdl result = (*local)(&argument, rqstp, transp, RPCBVERS4);
227 1.1 fvdl if (result != NULL && !svc_sendreply(transp, (xdrproc_t) xdr_result,
228 1.1 fvdl result)) {
229 1.1 fvdl svcerr_systemerr(transp);
230 1.1 fvdl if (debugging) {
231 1.1 fvdl (void) fprintf(stderr, "rpcbind: svc_sendreply\n");
232 1.1 fvdl if (doabort) {
233 1.1 fvdl rpcbind_abort();
234 1.1 fvdl }
235 1.1 fvdl }
236 1.1 fvdl }
237 1.1 fvdl done:
238 1.1 fvdl if (!svc_freeargs(transp, (xdrproc_t) xdr_argument,
239 1.1 fvdl (char *)&argument)) {
240 1.1 fvdl if (debugging) {
241 1.1 fvdl (void) fprintf(stderr, "unable to free arguments\n");
242 1.1 fvdl if (doabort) {
243 1.1 fvdl rpcbind_abort();
244 1.1 fvdl }
245 1.1 fvdl }
246 1.1 fvdl }
247 1.1 fvdl return;
248 1.1 fvdl }
249 1.1 fvdl
250 1.1 fvdl /*
251 1.1 fvdl * Lookup the mapping for a program, version and return its
252 1.1 fvdl * address. Assuming that the caller wants the address of the
253 1.1 fvdl * server running on the transport on which the request came.
254 1.1 fvdl * Even if a service with a different version number is available,
255 1.1 fvdl * it will return that address. The client should check with an
256 1.1 fvdl * clnt_call to verify whether the service is the one that is desired.
257 1.1 fvdl * We also try to resolve the universal address in terms of
258 1.1 fvdl * address of the caller.
259 1.1 fvdl */
260 1.1 fvdl /* ARGSUSED */
261 1.1 fvdl static void *
262 1.1 fvdl rpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
263 1.1 fvdl rpcvers_t rpcbversnum)
264 1.1 fvdl {
265 1.1 fvdl RPCB *regp = (RPCB *)arg;
266 1.1 fvdl #ifdef RPCBIND_DEBUG
267 1.1 fvdl if (debugging) {
268 1.1 fvdl char *uaddr;
269 1.1 fvdl
270 1.1 fvdl uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
271 1.1 fvdl svc_getrpccaller(transp));
272 1.1 fvdl fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
273 1.1 fvdl (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
274 1.1 fvdl regp->r_netid, uaddr);
275 1.1 fvdl free(uaddr);
276 1.1 fvdl }
277 1.1 fvdl #endif
278 1.1 fvdl return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
279 1.1 fvdl RPCB_ALLVERS));
280 1.1 fvdl }
281 1.1 fvdl
282 1.1 fvdl /*
283 1.1 fvdl * Lookup the mapping for a program, version and return its
284 1.1 fvdl * address. Assuming that the caller wants the address of the
285 1.1 fvdl * server running on the transport on which the request came.
286 1.1 fvdl *
287 1.1 fvdl * We also try to resolve the universal address in terms of
288 1.1 fvdl * address of the caller.
289 1.1 fvdl */
290 1.1 fvdl /* ARGSUSED */
291 1.1 fvdl static void *
292 1.1 fvdl rpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
293 1.1 fvdl rpcvers_t versnum)
294 1.1 fvdl {
295 1.1 fvdl RPCB *regp = (RPCB *)arg;
296 1.1 fvdl #ifdef RPCBIND_DEBUG
297 1.1 fvdl if (debugging) {
298 1.1 fvdl char *uaddr;
299 1.1 fvdl
300 1.1 fvdl uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
301 1.1 fvdl svc_getrpccaller(transp));
302 1.1 fvdl fprintf(stderr, "RPCB_GETVERSADDR rqst for (%lu, %lu, %s)"
303 1.1 fvdl " from %s : ",
304 1.1 fvdl (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
305 1.1 fvdl regp->r_netid, uaddr);
306 1.1 fvdl free(uaddr);
307 1.1 fvdl }
308 1.1 fvdl #endif
309 1.1 fvdl return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
310 1.1 fvdl RPCB_ONEVERS));
311 1.1 fvdl }
312 1.1 fvdl
313 1.1 fvdl /*
314 1.1 fvdl * Lookup the mapping for a program, version and return the
315 1.1 fvdl * addresses for all transports in the current transport family.
316 1.1 fvdl * We return a merged address.
317 1.1 fvdl */
318 1.1 fvdl /* ARGSUSED */
319 1.1 fvdl static void *
320 1.1 fvdl rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
321 1.1 fvdl rpcvers_t versnum)
322 1.1 fvdl {
323 1.1 fvdl RPCB *regp = (RPCB *)arg;
324 1.1 fvdl static rpcb_entry_list_ptr rlist;
325 1.1 fvdl register rpcblist_ptr rbl;
326 1.3 lukem rpcb_entry_list_ptr rp, tail = NULL;
327 1.1 fvdl rpcprog_t prog;
328 1.1 fvdl rpcvers_t vers;
329 1.1 fvdl rpcb_entry *a;
330 1.1 fvdl struct netconfig *nconf;
331 1.1 fvdl struct netconfig *reg_nconf;
332 1.1 fvdl char *saddr, *maddr = NULL;
333 1.1 fvdl
334 1.1 fvdl free_rpcb_entry_list(&rlist);
335 1.1 fvdl prog = regp->r_prog;
336 1.1 fvdl vers = regp->r_vers;
337 1.1 fvdl reg_nconf = rpcbind_get_conf(transp->xp_netid);
338 1.1 fvdl if (reg_nconf == NULL)
339 1.1 fvdl return (NULL);
340 1.1 fvdl if (*(regp->r_addr) != '\0') {
341 1.1 fvdl saddr = regp->r_addr;
342 1.1 fvdl } else {
343 1.1 fvdl saddr = NULL;
344 1.1 fvdl }
345 1.1 fvdl #ifdef RPCBIND_DEBUG
346 1.1 fvdl if (debugging) {
347 1.1 fvdl fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n",
348 1.1 fvdl regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly);
349 1.1 fvdl }
350 1.1 fvdl #endif
351 1.1 fvdl for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) {
352 1.1 fvdl if ((rbl->rpcb_map.r_prog == prog) &&
353 1.1 fvdl (rbl->rpcb_map.r_vers == vers)) {
354 1.1 fvdl nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid);
355 1.1 fvdl if (nconf == NULL)
356 1.1 fvdl goto fail;
357 1.1 fvdl if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly)
358 1.1 fvdl != 0) {
359 1.1 fvdl continue; /* not same proto family */
360 1.1 fvdl }
361 1.1 fvdl #ifdef RPCBIND_DEBUG
362 1.1 fvdl if (debugging)
363 1.2 fvdl fprintf(stderr, "\tmerge with: %s\n", rbl->rpcb_map.r_addr);
364 1.1 fvdl #endif
365 1.1 fvdl if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid,
366 1.1 fvdl rbl->rpcb_map.r_addr, saddr)) == NULL) {
367 1.1 fvdl #ifdef RPCBIND_DEBUG
368 1.1 fvdl if (debugging)
369 1.1 fvdl fprintf(stderr, " FAILED\n");
370 1.1 fvdl #endif
371 1.1 fvdl continue;
372 1.1 fvdl } else if (!maddr[0]) {
373 1.1 fvdl #ifdef RPCBIND_DEBUG
374 1.1 fvdl if (debugging)
375 1.1 fvdl fprintf(stderr, " SUCCEEDED, but port died - maddr: nullstring\n");
376 1.1 fvdl #endif
377 1.1 fvdl /* The server died. Unset this combination */
378 1.1 fvdl delete_prog(regp->r_prog);
379 1.4 christos free(maddr);
380 1.1 fvdl continue;
381 1.1 fvdl }
382 1.1 fvdl #ifdef RPCBIND_DEBUG
383 1.1 fvdl if (debugging)
384 1.1 fvdl fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr);
385 1.1 fvdl #endif
386 1.1 fvdl /*
387 1.1 fvdl * Add it to rlist.
388 1.1 fvdl */
389 1.1 fvdl rp = (rpcb_entry_list_ptr)
390 1.1 fvdl malloc((u_int)sizeof (rpcb_entry_list));
391 1.4 christos if (rp == NULL) {
392 1.4 christos free(maddr);
393 1.1 fvdl goto fail;
394 1.4 christos }
395 1.1 fvdl a = &rp->rpcb_entry_map;
396 1.1 fvdl a->r_maddr = maddr;
397 1.1 fvdl a->r_nc_netid = nconf->nc_netid;
398 1.1 fvdl a->r_nc_semantics = nconf->nc_semantics;
399 1.1 fvdl a->r_nc_protofmly = nconf->nc_protofmly;
400 1.1 fvdl a->r_nc_proto = nconf->nc_proto;
401 1.1 fvdl rp->rpcb_entry_next = NULL;
402 1.1 fvdl if (rlist == NULL) {
403 1.1 fvdl rlist = rp;
404 1.1 fvdl tail = rp;
405 1.5 christos } else if (tail) {
406 1.1 fvdl tail->rpcb_entry_next = rp;
407 1.1 fvdl tail = rp;
408 1.1 fvdl }
409 1.1 fvdl rp = NULL;
410 1.1 fvdl }
411 1.1 fvdl }
412 1.1 fvdl #ifdef RPCBIND_DEBUG
413 1.1 fvdl if (debugging) {
414 1.1 fvdl for (rp = rlist; rp; rp = rp->rpcb_entry_next) {
415 1.1 fvdl fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr,
416 1.1 fvdl rp->rpcb_entry_map.r_nc_proto);
417 1.1 fvdl }
418 1.1 fvdl }
419 1.1 fvdl #endif
420 1.1 fvdl /*
421 1.1 fvdl * XXX: getaddrlist info is also being stuffed into getaddr.
422 1.1 fvdl * Perhaps wrong, but better than it not getting counted at all.
423 1.1 fvdl */
424 1.1 fvdl rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr);
425 1.1 fvdl return (void *)&rlist;
426 1.1 fvdl
427 1.1 fvdl fail: free_rpcb_entry_list(&rlist);
428 1.1 fvdl return (NULL);
429 1.1 fvdl }
430 1.1 fvdl
431 1.1 fvdl /*
432 1.1 fvdl * Free only the allocated structure, rest is all a pointer to some
433 1.1 fvdl * other data somewhere else.
434 1.1 fvdl */
435 1.1 fvdl static void
436 1.1 fvdl free_rpcb_entry_list(rpcb_entry_list_ptr *rlistp)
437 1.1 fvdl {
438 1.1 fvdl register rpcb_entry_list_ptr rbl, tmp;
439 1.1 fvdl
440 1.1 fvdl for (rbl = *rlistp; rbl != NULL; ) {
441 1.1 fvdl tmp = rbl;
442 1.1 fvdl rbl = rbl->rpcb_entry_next;
443 1.1 fvdl free((char *)tmp->rpcb_entry_map.r_maddr);
444 1.1 fvdl free((char *)tmp);
445 1.1 fvdl }
446 1.1 fvdl *rlistp = NULL;
447 1.1 fvdl }
448 1.1 fvdl
449 1.1 fvdl /* ARGSUSED */
450 1.1 fvdl static void *
451 1.1 fvdl rpcbproc_dump_4_local(void *arg, struct svc_req *req, SVCXPRT *xprt,
452 1.1 fvdl rpcvers_t versnum)
453 1.1 fvdl {
454 1.1 fvdl return ((void *)&list_rbl);
455 1.1 fvdl }
456