bool_t rpcbproc_getaddr_com(rpcb *regp, char **result, ar_svc_req_t *rqstp, arpcvers_t rpcbversnum, arpcvers_t verstype) { char *uaddr; char *saddr; const char *netidstr; rpcblist_ptr fnd; uaddr = NULL; saddr = NULL; if (!ar_svc_control(rqstp->rq_xprt, AR_SVCGET_NETID, &netidstr)) { ar_svcflgerr_systemerr(rqstp); return FALSE; } fnd = find_service(regp->r_prog, regp->r_vers, netidstr); if (fnd && ((verstype == RPCB_ALLVERS) || (regp->r_vers == fnd->rpcb_map.r_vers))) { if (*(regp->r_addr) != '\0') { /* may contain a hint about */ saddr = regp->r_addr; /* the interface that we */ } /* should use */ if (!(uaddr = mergeaddr(rqstp->rq_xprt, netidstr, fnd->rpcb_map.r_addr, saddr))) { /* Try whatever we have */ uaddr = strdup(fnd->rpcb_map.r_addr); } else if (!uaddr[0]) { /* * The server died. Unset all versions of this prog. */ delete_prog(regp->r_prog); uaddr = strdup(""); } } else { uaddr = strdup(""); } if (!uaddr) { ar_svcflgerr_systemerr(rqstp); return FALSE; } #ifdef RPCBIND_DEBUG if (debugging) { fprintf(stderr, "getaddr: %s\n", uaddr); } #endif /* XXX: should have used some defined constant here */ rpcbs_getaddr(rpcbversnum - 2, regp->r_prog, regp->r_vers, netidstr, uaddr); *result = uaddr; return TRUE; }
/* ARGSUSED */ static void * rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp /*__unused*/, SVCXPRT *transp, rpcvers_t versnum /*__unused*/) { RPCB *regp = (RPCB *)arg; static rpcb_entry_list_ptr rlist; register rpcblist_ptr rbl; rpcb_entry_list_ptr rp, tail; rpcprog_t prog; rpcvers_t vers; rpcb_entry *a; struct netconfig *nconf; struct netconfig *reg_nconf; char *saddr, *maddr = NULL; free_rpcb_entry_list(&rlist); tail = NULL; prog = regp->r_prog; vers = regp->r_vers; reg_nconf = rpcbind_get_conf(transp->xp_netid); if (reg_nconf == NULL) return (NULL); if (*(regp->r_addr) != '\0') { saddr = regp->r_addr; } else { saddr = NULL; } #ifdef RPCBIND_DEBUG if (debugging) { fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n", regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly); } #endif for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) { if ((rbl->rpcb_map.r_prog == prog) && (rbl->rpcb_map.r_vers == vers)) { nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid); if (nconf == NULL) goto fail; if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly) != 0) { continue; /* not same proto family */ } #ifdef RPCBIND_DEBUG if (debugging) fprintf(stderr, "\tmerge with: %s\n", rbl->rpcb_map.r_addr); #endif if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid, rbl->rpcb_map.r_addr, saddr)) == NULL) { #ifdef RPCBIND_DEBUG if (debugging) fprintf(stderr, " FAILED\n"); #endif continue; } else if (!maddr[0]) { #ifdef RPCBIND_DEBUG if (debugging) fprintf(stderr, " SUCCEEDED, but port died - maddr: nullstring\n"); #endif /* The server died. Unset this combination */ delete_prog(regp->r_prog); continue; } #ifdef RPCBIND_DEBUG if (debugging) fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr); #endif /* * Add it to rlist. */ rp = malloc(sizeof (rpcb_entry_list)); if (rp == NULL) goto fail; a = &rp->rpcb_entry_map; a->r_maddr = maddr; a->r_nc_netid = nconf->nc_netid; a->r_nc_semantics = nconf->nc_semantics; a->r_nc_protofmly = nconf->nc_protofmly; a->r_nc_proto = nconf->nc_proto; rp->rpcb_entry_next = NULL; if (rlist == NULL) { rlist = rp; tail = rp; } else { tail->rpcb_entry_next = rp; tail = rp; } rp = NULL; } } #ifdef RPCBIND_DEBUG if (debugging) { for (rp = rlist; rp; rp = rp->rpcb_entry_next) { fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr, rp->rpcb_entry_map.r_nc_proto); } } #endif /* * XXX: getaddrlist info is also being stuffed into getaddr. * Perhaps wrong, but better than it not getting counted at all. */ rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr); return (void *)&rlist; fail: free_rpcb_entry_list(&rlist); return (NULL); }