1 1.9 christos /* $NetBSD: rpcb_svc_4.c,v 1.9 2019/01/03 19:04:21 christos Exp $ */ 2 1.8 christos /* $FreeBSD: head/usr.sbin/rpcbind/rpcb_svc_4.c 258564 2013-11-25 16:44:02Z hrs $ */ 3 1.1 fvdl 4 1.8 christos /*- 5 1.8 christos * Copyright (c) 2009, Sun Microsystems, Inc. 6 1.8 christos * All rights reserved. 7 1.8 christos * 8 1.8 christos * Redistribution and use in source and binary forms, with or without 9 1.8 christos * modification, are permitted provided that the following conditions are met: 10 1.8 christos * - Redistributions of source code must retain the above copyright notice, 11 1.8 christos * this list of conditions and the following disclaimer. 12 1.8 christos * - Redistributions in binary form must reproduce the above copyright notice, 13 1.8 christos * this list of conditions and the following disclaimer in the documentation 14 1.8 christos * and/or other materials provided with the distribution. 15 1.8 christos * - Neither the name of Sun Microsystems, Inc. nor the names of its 16 1.8 christos * contributors may be used to endorse or promote products derived 17 1.8 christos * from this software without specific prior written permission. 18 1.8 christos * 19 1.8 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 1.8 christos * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.8 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.8 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 1.8 christos * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.8 christos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.8 christos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.8 christos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.8 christos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.8 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.8 christos * POSSIBILITY OF SUCH DAMAGE. 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.8 christos rpcvers_t rpcbversnum __unused) 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.8 christos rpcvers_t versnum __unused) 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.8 christos rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp __unused, 321 1.8 christos SVCXPRT *transp, rpcvers_t versnum __unused) 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.8 christos rpcb_entry_list_ptr rp, tail; 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.8 christos tail = NULL; 336 1.1 fvdl prog = regp->r_prog; 337 1.1 fvdl vers = regp->r_vers; 338 1.1 fvdl reg_nconf = rpcbind_get_conf(transp->xp_netid); 339 1.1 fvdl if (reg_nconf == NULL) 340 1.1 fvdl return (NULL); 341 1.1 fvdl if (*(regp->r_addr) != '\0') { 342 1.1 fvdl saddr = regp->r_addr; 343 1.1 fvdl } else { 344 1.1 fvdl saddr = NULL; 345 1.1 fvdl } 346 1.1 fvdl #ifdef RPCBIND_DEBUG 347 1.1 fvdl if (debugging) { 348 1.1 fvdl fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n", 349 1.1 fvdl regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly); 350 1.1 fvdl } 351 1.1 fvdl #endif 352 1.1 fvdl for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) { 353 1.1 fvdl if ((rbl->rpcb_map.r_prog == prog) && 354 1.1 fvdl (rbl->rpcb_map.r_vers == vers)) { 355 1.1 fvdl nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid); 356 1.1 fvdl if (nconf == NULL) 357 1.1 fvdl goto fail; 358 1.1 fvdl if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly) 359 1.1 fvdl != 0) { 360 1.1 fvdl continue; /* not same proto family */ 361 1.1 fvdl } 362 1.1 fvdl #ifdef RPCBIND_DEBUG 363 1.1 fvdl if (debugging) 364 1.8 christos fprintf(stderr, "\tmerge with: %s\n", 365 1.8 christos rbl->rpcb_map.r_addr); 366 1.1 fvdl #endif 367 1.1 fvdl if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid, 368 1.1 fvdl rbl->rpcb_map.r_addr, saddr)) == NULL) { 369 1.1 fvdl #ifdef RPCBIND_DEBUG 370 1.1 fvdl if (debugging) 371 1.1 fvdl fprintf(stderr, " FAILED\n"); 372 1.1 fvdl #endif 373 1.1 fvdl continue; 374 1.1 fvdl } else if (!maddr[0]) { 375 1.1 fvdl #ifdef RPCBIND_DEBUG 376 1.1 fvdl if (debugging) 377 1.1 fvdl fprintf(stderr, " SUCCEEDED, but port died - maddr: nullstring\n"); 378 1.1 fvdl #endif 379 1.1 fvdl /* The server died. Unset this combination */ 380 1.1 fvdl delete_prog(regp->r_prog); 381 1.1 fvdl continue; 382 1.1 fvdl } 383 1.1 fvdl #ifdef RPCBIND_DEBUG 384 1.1 fvdl if (debugging) 385 1.1 fvdl fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr); 386 1.1 fvdl #endif 387 1.1 fvdl /* 388 1.1 fvdl * Add it to rlist. 389 1.1 fvdl */ 390 1.9 christos rp = malloc(sizeof(*rp)); 391 1.8 christos if (rp == NULL) 392 1.1 fvdl goto fail; 393 1.1 fvdl a = &rp->rpcb_entry_map; 394 1.1 fvdl a->r_maddr = maddr; 395 1.1 fvdl a->r_nc_netid = nconf->nc_netid; 396 1.1 fvdl a->r_nc_semantics = nconf->nc_semantics; 397 1.1 fvdl a->r_nc_protofmly = nconf->nc_protofmly; 398 1.1 fvdl a->r_nc_proto = nconf->nc_proto; 399 1.1 fvdl rp->rpcb_entry_next = NULL; 400 1.1 fvdl if (rlist == NULL) { 401 1.1 fvdl rlist = rp; 402 1.1 fvdl tail = rp; 403 1.5 christos } else if (tail) { 404 1.1 fvdl tail->rpcb_entry_next = rp; 405 1.1 fvdl tail = rp; 406 1.1 fvdl } 407 1.1 fvdl rp = NULL; 408 1.1 fvdl } 409 1.1 fvdl } 410 1.1 fvdl #ifdef RPCBIND_DEBUG 411 1.1 fvdl if (debugging) { 412 1.1 fvdl for (rp = rlist; rp; rp = rp->rpcb_entry_next) { 413 1.1 fvdl fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr, 414 1.1 fvdl rp->rpcb_entry_map.r_nc_proto); 415 1.1 fvdl } 416 1.1 fvdl } 417 1.1 fvdl #endif 418 1.1 fvdl /* 419 1.1 fvdl * XXX: getaddrlist info is also being stuffed into getaddr. 420 1.1 fvdl * Perhaps wrong, but better than it not getting counted at all. 421 1.1 fvdl */ 422 1.1 fvdl rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr); 423 1.1 fvdl return (void *)&rlist; 424 1.1 fvdl 425 1.1 fvdl fail: free_rpcb_entry_list(&rlist); 426 1.1 fvdl return (NULL); 427 1.1 fvdl } 428 1.1 fvdl 429 1.1 fvdl /* 430 1.1 fvdl * Free only the allocated structure, rest is all a pointer to some 431 1.1 fvdl * other data somewhere else. 432 1.1 fvdl */ 433 1.1 fvdl static void 434 1.1 fvdl free_rpcb_entry_list(rpcb_entry_list_ptr *rlistp) 435 1.1 fvdl { 436 1.1 fvdl register rpcb_entry_list_ptr rbl, tmp; 437 1.1 fvdl 438 1.1 fvdl for (rbl = *rlistp; rbl != NULL; ) { 439 1.1 fvdl tmp = rbl; 440 1.1 fvdl rbl = rbl->rpcb_entry_next; 441 1.1 fvdl free((char *)tmp->rpcb_entry_map.r_maddr); 442 1.1 fvdl free((char *)tmp); 443 1.1 fvdl } 444 1.1 fvdl *rlistp = NULL; 445 1.1 fvdl } 446 1.1 fvdl 447 1.1 fvdl /* ARGSUSED */ 448 1.1 fvdl static void * 449 1.8 christos rpcbproc_dump_4_local(void *arg __unused, struct svc_req *req __unused, 450 1.8 christos SVCXPRT *xprt __unused, rpcvers_t versnum __unused) 451 1.1 fvdl { 452 1.1 fvdl return ((void *)&list_rbl); 453 1.1 fvdl } 454