1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate * 22*7c478bd9Sstevel@tonic-gate * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 23*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*7c478bd9Sstevel@tonic-gate */ 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 28*7c478bd9Sstevel@tonic-gate /* 29*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 30*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 31*7c478bd9Sstevel@tonic-gate * All Rights Reserved 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 34*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 35*7c478bd9Sstevel@tonic-gate * contributors. 36*7c478bd9Sstevel@tonic-gate */ 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate /* 41*7c478bd9Sstevel@tonic-gate * check_bound.c 42*7c478bd9Sstevel@tonic-gate * Checks to see whether the program is still bound to the 43*7c478bd9Sstevel@tonic-gate * claimed address and returns the univeral merged address 44*7c478bd9Sstevel@tonic-gate * 45*7c478bd9Sstevel@tonic-gate */ 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate #include <stdio.h> 48*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 49*7c478bd9Sstevel@tonic-gate #include <netconfig.h> 50*7c478bd9Sstevel@tonic-gate #include <netdir.h> 51*7c478bd9Sstevel@tonic-gate #include <sys/syslog.h> 52*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 53*7c478bd9Sstevel@tonic-gate #include "rpcbind.h" 54*7c478bd9Sstevel@tonic-gate #include <string.h> 55*7c478bd9Sstevel@tonic-gate /* the following just to get my address */ 56*7c478bd9Sstevel@tonic-gate #include <errno.h> 57*7c478bd9Sstevel@tonic-gate #include <sys/socket.h> 58*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate struct fdlist { 61*7c478bd9Sstevel@tonic-gate int fd; 62*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 63*7c478bd9Sstevel@tonic-gate struct fdlist *next; 64*7c478bd9Sstevel@tonic-gate int check_binding; 65*7c478bd9Sstevel@tonic-gate }; 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate static struct fdlist *fdhead; /* Link list of the check fd's */ 68*7c478bd9Sstevel@tonic-gate static struct fdlist *fdtail; 69*7c478bd9Sstevel@tonic-gate static char *nullstring = ""; 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate /* 72*7c478bd9Sstevel@tonic-gate * Returns 1 if the given address is bound for the given addr & transport 73*7c478bd9Sstevel@tonic-gate * For all error cases, we assume that the address is bound 74*7c478bd9Sstevel@tonic-gate * Returns 0 for success. 75*7c478bd9Sstevel@tonic-gate */ 76*7c478bd9Sstevel@tonic-gate static bool_t 77*7c478bd9Sstevel@tonic-gate check_bound(fdl, uaddr) 78*7c478bd9Sstevel@tonic-gate struct fdlist *fdl; /* My FD list */ 79*7c478bd9Sstevel@tonic-gate char *uaddr; /* the universal address */ 80*7c478bd9Sstevel@tonic-gate { 81*7c478bd9Sstevel@tonic-gate int fd; 82*7c478bd9Sstevel@tonic-gate struct netbuf *na; 83*7c478bd9Sstevel@tonic-gate struct t_bind taddr, *baddr; 84*7c478bd9Sstevel@tonic-gate int ans; 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate if (fdl->check_binding == FALSE) 87*7c478bd9Sstevel@tonic-gate return (TRUE); 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate na = uaddr2taddr(fdl->nconf, uaddr); 90*7c478bd9Sstevel@tonic-gate if (!na) 91*7c478bd9Sstevel@tonic-gate return (TRUE); /* punt, should never happen */ 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate fd = fdl->fd; 94*7c478bd9Sstevel@tonic-gate taddr.addr = *na; 95*7c478bd9Sstevel@tonic-gate taddr.qlen = 1; 96*7c478bd9Sstevel@tonic-gate baddr = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR); 97*7c478bd9Sstevel@tonic-gate if (baddr == NULL) { 98*7c478bd9Sstevel@tonic-gate netdir_free((char *)na, ND_ADDR); 99*7c478bd9Sstevel@tonic-gate return (TRUE); 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate if (t_bind(fd, &taddr, baddr) != 0) { 102*7c478bd9Sstevel@tonic-gate netdir_free((char *)na, ND_ADDR); 103*7c478bd9Sstevel@tonic-gate (void) t_free((char *)baddr, T_BIND); 104*7c478bd9Sstevel@tonic-gate return (TRUE); 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate ans = memcmp(taddr.addr.buf, baddr->addr.buf, baddr->addr.len); 107*7c478bd9Sstevel@tonic-gate netdir_free((char *)na, ND_ADDR); 108*7c478bd9Sstevel@tonic-gate (void) t_free((char *)baddr, T_BIND); 109*7c478bd9Sstevel@tonic-gate if (t_unbind(fd) != 0) { 110*7c478bd9Sstevel@tonic-gate /* Bad fd. Purge this fd */ 111*7c478bd9Sstevel@tonic-gate (void) t_close(fd); 112*7c478bd9Sstevel@tonic-gate fdl->fd = t_open(fdl->nconf->nc_device, O_RDWR, NULL); 113*7c478bd9Sstevel@tonic-gate if (fdl->fd == -1) 114*7c478bd9Sstevel@tonic-gate fdl->check_binding = FALSE; 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate return (ans == 0 ? FALSE : TRUE); 117*7c478bd9Sstevel@tonic-gate } 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate /* 120*7c478bd9Sstevel@tonic-gate * Keep open one more file descriptor for this transport, which 121*7c478bd9Sstevel@tonic-gate * will be used to determine whether the given service is up 122*7c478bd9Sstevel@tonic-gate * or not by trying to bind to the registered address. 123*7c478bd9Sstevel@tonic-gate * We are ignoring errors here. It trashes taddr and baddr; 124*7c478bd9Sstevel@tonic-gate * but that perhaps should not matter. 125*7c478bd9Sstevel@tonic-gate * 126*7c478bd9Sstevel@tonic-gate * We check for the following conditions: 127*7c478bd9Sstevel@tonic-gate * 1. Is it possible for t_bind to fail in the case where 128*7c478bd9Sstevel@tonic-gate * we bind to an already bound address and have any 129*7c478bd9Sstevel@tonic-gate * other error number besides TNOADDR. 130*7c478bd9Sstevel@tonic-gate * 2. If a address is specified in bind addr, can I bind to 131*7c478bd9Sstevel@tonic-gate * the same address. 132*7c478bd9Sstevel@tonic-gate * 3. If NULL is specified in bind addr, can I bind to the 133*7c478bd9Sstevel@tonic-gate * address to which the fd finally got bound. 134*7c478bd9Sstevel@tonic-gate */ 135*7c478bd9Sstevel@tonic-gate int 136*7c478bd9Sstevel@tonic-gate add_bndlist(nconf, taddr, baddr) 137*7c478bd9Sstevel@tonic-gate struct netconfig *nconf; 138*7c478bd9Sstevel@tonic-gate struct t_bind *taddr, *baddr; 139*7c478bd9Sstevel@tonic-gate { 140*7c478bd9Sstevel@tonic-gate int fd; 141*7c478bd9Sstevel@tonic-gate struct fdlist *fdl; 142*7c478bd9Sstevel@tonic-gate struct netconfig *newnconf; 143*7c478bd9Sstevel@tonic-gate struct t_info tinfo; 144*7c478bd9Sstevel@tonic-gate struct t_bind tmpaddr; 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate newnconf = getnetconfigent(nconf->nc_netid); 147*7c478bd9Sstevel@tonic-gate if (newnconf == NULL) 148*7c478bd9Sstevel@tonic-gate return (-1); 149*7c478bd9Sstevel@tonic-gate fdl = (struct fdlist *)malloc((uint_t)sizeof (struct fdlist)); 150*7c478bd9Sstevel@tonic-gate if (fdl == NULL) { 151*7c478bd9Sstevel@tonic-gate freenetconfigent(newnconf); 152*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "no memory!"); 153*7c478bd9Sstevel@tonic-gate return (-1); 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate fdl->nconf = newnconf; 156*7c478bd9Sstevel@tonic-gate fdl->next = NULL; 157*7c478bd9Sstevel@tonic-gate if (fdhead == NULL) { 158*7c478bd9Sstevel@tonic-gate fdhead = fdl; 159*7c478bd9Sstevel@tonic-gate fdtail = fdl; 160*7c478bd9Sstevel@tonic-gate } else { 161*7c478bd9Sstevel@tonic-gate fdtail->next = fdl; 162*7c478bd9Sstevel@tonic-gate fdtail = fdl; 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate fdl->check_binding = FALSE; 165*7c478bd9Sstevel@tonic-gate if ((fdl->fd = t_open(nconf->nc_device, O_RDWR, &tinfo)) < 0) { 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * Note that we haven't dequeued this entry nor have we freed 168*7c478bd9Sstevel@tonic-gate * the netconfig structure. 169*7c478bd9Sstevel@tonic-gate */ 170*7c478bd9Sstevel@tonic-gate if (debugging) { 171*7c478bd9Sstevel@tonic-gate fprintf(stderr, 172*7c478bd9Sstevel@tonic-gate "%s: add_bndlist cannot open connection: %s", 173*7c478bd9Sstevel@tonic-gate nconf->nc_netid, t_errlist[t_errno]); 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate return (-1); 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate /* Set the qlen only for cots transports */ 179*7c478bd9Sstevel@tonic-gate switch (tinfo.servtype) { 180*7c478bd9Sstevel@tonic-gate case T_COTS: 181*7c478bd9Sstevel@tonic-gate case T_COTS_ORD: 182*7c478bd9Sstevel@tonic-gate taddr->qlen = 1; 183*7c478bd9Sstevel@tonic-gate break; 184*7c478bd9Sstevel@tonic-gate case T_CLTS: 185*7c478bd9Sstevel@tonic-gate taddr->qlen = 0; 186*7c478bd9Sstevel@tonic-gate break; 187*7c478bd9Sstevel@tonic-gate default: 188*7c478bd9Sstevel@tonic-gate goto error; 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate if (t_bind(fdl->fd, taddr, baddr) != 0) { 192*7c478bd9Sstevel@tonic-gate if (t_errno == TNOADDR) { 193*7c478bd9Sstevel@tonic-gate fdl->check_binding = TRUE; 194*7c478bd9Sstevel@tonic-gate return (0); /* All is fine */ 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate /* Perhaps condition #1 */ 197*7c478bd9Sstevel@tonic-gate if (debugging) { 198*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: add_bndlist cannot bind (1): %s", 199*7c478bd9Sstevel@tonic-gate nconf->nc_netid, t_errlist[t_errno]); 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate goto not_bound; 202*7c478bd9Sstevel@tonic-gate } 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate /* Condition #2 */ 205*7c478bd9Sstevel@tonic-gate if (!memcmp(taddr->addr.buf, baddr->addr.buf, 206*7c478bd9Sstevel@tonic-gate (int)baddr->addr.len)) { 207*7c478bd9Sstevel@tonic-gate #ifdef BIND_DEBUG 208*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Condition #2\n"); 209*7c478bd9Sstevel@tonic-gate #endif 210*7c478bd9Sstevel@tonic-gate goto not_bound; 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate /* Condition #3 */ 214*7c478bd9Sstevel@tonic-gate t_unbind(fdl->fd); 215*7c478bd9Sstevel@tonic-gate /* Set the qlen only for cots transports */ 216*7c478bd9Sstevel@tonic-gate switch (tinfo.servtype) { 217*7c478bd9Sstevel@tonic-gate case T_COTS: 218*7c478bd9Sstevel@tonic-gate case T_COTS_ORD: 219*7c478bd9Sstevel@tonic-gate tmpaddr.qlen = 1; 220*7c478bd9Sstevel@tonic-gate break; 221*7c478bd9Sstevel@tonic-gate case T_CLTS: 222*7c478bd9Sstevel@tonic-gate tmpaddr.qlen = 0; 223*7c478bd9Sstevel@tonic-gate break; 224*7c478bd9Sstevel@tonic-gate default: 225*7c478bd9Sstevel@tonic-gate goto error; 226*7c478bd9Sstevel@tonic-gate } 227*7c478bd9Sstevel@tonic-gate tmpaddr.addr.len = tmpaddr.addr.maxlen = 0; 228*7c478bd9Sstevel@tonic-gate tmpaddr.addr.buf = NULL; 229*7c478bd9Sstevel@tonic-gate if (t_bind(fdl->fd, &tmpaddr, taddr) != 0) { 230*7c478bd9Sstevel@tonic-gate if (debugging) { 231*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: add_bndlist cannot bind (2): %s", 232*7c478bd9Sstevel@tonic-gate nconf->nc_netid, t_errlist[t_errno]); 233*7c478bd9Sstevel@tonic-gate } 234*7c478bd9Sstevel@tonic-gate goto error; 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate /* Now fdl->fd is bound to a transport chosen address */ 237*7c478bd9Sstevel@tonic-gate if ((fd = t_open(nconf->nc_device, O_RDWR, &tinfo)) < 0) { 238*7c478bd9Sstevel@tonic-gate if (debugging) { 239*7c478bd9Sstevel@tonic-gate fprintf(stderr, 240*7c478bd9Sstevel@tonic-gate "%s: add_bndlist cannot open connection: %s", 241*7c478bd9Sstevel@tonic-gate nconf->nc_netid, t_errlist[t_errno]); 242*7c478bd9Sstevel@tonic-gate } 243*7c478bd9Sstevel@tonic-gate goto error; 244*7c478bd9Sstevel@tonic-gate } 245*7c478bd9Sstevel@tonic-gate if (t_bind(fd, taddr, baddr) != 0) { 246*7c478bd9Sstevel@tonic-gate if (t_errno == TNOADDR) { 247*7c478bd9Sstevel@tonic-gate /* 248*7c478bd9Sstevel@tonic-gate * This transport is schizo. Previously it handled a 249*7c478bd9Sstevel@tonic-gate * request to bind to an already bound transport by 250*7c478bd9Sstevel@tonic-gate * returning a different bind address, and now it's 251*7c478bd9Sstevel@tonic-gate * returning a TNOADDR for essentially the same 252*7c478bd9Sstevel@tonic-gate * request. The spec may allow this behavior, so 253*7c478bd9Sstevel@tonic-gate * we'll just assume we can't do bind checking with 254*7c478bd9Sstevel@tonic-gate * this transport. 255*7c478bd9Sstevel@tonic-gate */ 256*7c478bd9Sstevel@tonic-gate goto not_bound; 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate if (debugging) { 259*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: add_bndlist cannot bind (3): %s", 260*7c478bd9Sstevel@tonic-gate nconf->nc_netid, t_errlist[t_errno]); 261*7c478bd9Sstevel@tonic-gate } 262*7c478bd9Sstevel@tonic-gate t_close(fd); 263*7c478bd9Sstevel@tonic-gate goto error; 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate t_close(fd); 266*7c478bd9Sstevel@tonic-gate if (!memcmp(taddr->addr.buf, baddr->addr.buf, 267*7c478bd9Sstevel@tonic-gate (int)baddr->addr.len)) { 268*7c478bd9Sstevel@tonic-gate switch (tinfo.servtype) { 269*7c478bd9Sstevel@tonic-gate case T_COTS: 270*7c478bd9Sstevel@tonic-gate case T_COTS_ORD: 271*7c478bd9Sstevel@tonic-gate if (baddr->qlen == 1) { 272*7c478bd9Sstevel@tonic-gate #ifdef BIND_DEBUG 273*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Condition #3\n"); 274*7c478bd9Sstevel@tonic-gate #endif 275*7c478bd9Sstevel@tonic-gate goto not_bound; 276*7c478bd9Sstevel@tonic-gate } 277*7c478bd9Sstevel@tonic-gate break; 278*7c478bd9Sstevel@tonic-gate case T_CLTS: 279*7c478bd9Sstevel@tonic-gate #ifdef BIND_DEBUG 280*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Condition #3\n"); 281*7c478bd9Sstevel@tonic-gate #endif 282*7c478bd9Sstevel@tonic-gate goto not_bound; 283*7c478bd9Sstevel@tonic-gate default: 284*7c478bd9Sstevel@tonic-gate goto error; 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate t_unbind(fdl->fd); 289*7c478bd9Sstevel@tonic-gate fdl->check_binding = TRUE; 290*7c478bd9Sstevel@tonic-gate return (0); 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate not_bound: 293*7c478bd9Sstevel@tonic-gate t_close(fdl->fd); 294*7c478bd9Sstevel@tonic-gate fdl->fd = -1; 295*7c478bd9Sstevel@tonic-gate return (1); 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate error: 298*7c478bd9Sstevel@tonic-gate t_close(fdl->fd); 299*7c478bd9Sstevel@tonic-gate fdl->fd = -1; 300*7c478bd9Sstevel@tonic-gate return (-1); 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate bool_t 304*7c478bd9Sstevel@tonic-gate is_bound(netid, uaddr) 305*7c478bd9Sstevel@tonic-gate char *netid; 306*7c478bd9Sstevel@tonic-gate char *uaddr; 307*7c478bd9Sstevel@tonic-gate { 308*7c478bd9Sstevel@tonic-gate struct fdlist *fdl; 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate for (fdl = fdhead; fdl; fdl = fdl->next) 311*7c478bd9Sstevel@tonic-gate if (strcmp(fdl->nconf->nc_netid, netid) == 0) 312*7c478bd9Sstevel@tonic-gate break; 313*7c478bd9Sstevel@tonic-gate if (fdl == NULL) 314*7c478bd9Sstevel@tonic-gate return (TRUE); 315*7c478bd9Sstevel@tonic-gate return (check_bound(fdl, uaddr)); 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate /* Return pointer to port string in the universal address */ 319*7c478bd9Sstevel@tonic-gate #define UADDR_PRT_INDX(UADDR, PORT) { \ 320*7c478bd9Sstevel@tonic-gate PORT = strrchr(UADDR, '.'); \ 321*7c478bd9Sstevel@tonic-gate while (*--PORT != '.'); } 322*7c478bd9Sstevel@tonic-gate /* 323*7c478bd9Sstevel@tonic-gate * Returns NULL if there was some system error. 324*7c478bd9Sstevel@tonic-gate * Returns "" if the address was not bound, i.e the server crashed. 325*7c478bd9Sstevel@tonic-gate * Returns the merged address otherwise. 326*7c478bd9Sstevel@tonic-gate */ 327*7c478bd9Sstevel@tonic-gate char * 328*7c478bd9Sstevel@tonic-gate mergeaddr(xprt, netid, uaddr, saddr) 329*7c478bd9Sstevel@tonic-gate SVCXPRT *xprt; 330*7c478bd9Sstevel@tonic-gate char *netid; 331*7c478bd9Sstevel@tonic-gate char *uaddr; 332*7c478bd9Sstevel@tonic-gate char *saddr; 333*7c478bd9Sstevel@tonic-gate { 334*7c478bd9Sstevel@tonic-gate struct fdlist *fdl; 335*7c478bd9Sstevel@tonic-gate struct nd_mergearg ma; 336*7c478bd9Sstevel@tonic-gate int stat; 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate for (fdl = fdhead; fdl; fdl = fdl->next) 339*7c478bd9Sstevel@tonic-gate if (strcmp(fdl->nconf->nc_netid, netid) == 0) 340*7c478bd9Sstevel@tonic-gate break; 341*7c478bd9Sstevel@tonic-gate if (fdl == NULL) 342*7c478bd9Sstevel@tonic-gate return (NULL); 343*7c478bd9Sstevel@tonic-gate if (check_bound(fdl, uaddr) == FALSE) 344*7c478bd9Sstevel@tonic-gate /* that server died */ 345*7c478bd9Sstevel@tonic-gate return (nullstring); 346*7c478bd9Sstevel@tonic-gate /* 347*7c478bd9Sstevel@tonic-gate * If saddr is not NULL, the remote client may have included the 348*7c478bd9Sstevel@tonic-gate * address by which it contacted us. Use that for the "client" uaddr, 349*7c478bd9Sstevel@tonic-gate * otherwise use the info from the SVCXPRT. 350*7c478bd9Sstevel@tonic-gate */ 351*7c478bd9Sstevel@tonic-gate if (saddr != NULL) { 352*7c478bd9Sstevel@tonic-gate ma.c_uaddr = saddr; 353*7c478bd9Sstevel@tonic-gate } else { 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate /* retrieve the client's address */ 356*7c478bd9Sstevel@tonic-gate ma.c_uaddr = taddr2uaddr(fdl->nconf, svc_getrpccaller(xprt)); 357*7c478bd9Sstevel@tonic-gate if (ma.c_uaddr == NULL) { 358*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "taddr2uaddr failed for %s: %s", 359*7c478bd9Sstevel@tonic-gate fdl->nconf->nc_netid, netdir_sperror()); 360*7c478bd9Sstevel@tonic-gate return (NULL); 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate #ifdef ND_DEBUG 365*7c478bd9Sstevel@tonic-gate if (saddr == NULL) { 366*7c478bd9Sstevel@tonic-gate fprintf(stderr, "mergeaddr: client uaddr = %s\n", ma.c_uaddr); 367*7c478bd9Sstevel@tonic-gate } else { 368*7c478bd9Sstevel@tonic-gate fprintf(stderr, "mergeaddr: contact uaddr = %s\n", ma.c_uaddr); 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate #endif 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate /* Not an INET adaress? */ 373*7c478bd9Sstevel@tonic-gate if ((strcmp(fdl->nconf->nc_protofmly, NC_INET) != 0) && 374*7c478bd9Sstevel@tonic-gate (strcmp(fdl->nconf->nc_protofmly, NC_INET6) != 0)) { 375*7c478bd9Sstevel@tonic-gate ma.s_uaddr = uaddr; 376*7c478bd9Sstevel@tonic-gate #ifdef ND_DEBUG 377*7c478bd9Sstevel@tonic-gate fprintf(stderr, "mergeaddr: Call to the original" 378*7c478bd9Sstevel@tonic-gate " ND_MERGEADDR interface\n"); 379*7c478bd9Sstevel@tonic-gate #endif 380*7c478bd9Sstevel@tonic-gate stat = netdir_options(fdl->nconf, ND_MERGEADDR, 0, (char *)&ma); 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate /* Inet address, but no xp_ltaddr */ 383*7c478bd9Sstevel@tonic-gate else if ((ma.s_uaddr = taddr2uaddr(fdl->nconf, 384*7c478bd9Sstevel@tonic-gate &(xprt)->xp_ltaddr)) == NULL) { 385*7c478bd9Sstevel@tonic-gate ma.s_uaddr = uaddr; 386*7c478bd9Sstevel@tonic-gate #ifdef ND_DEBUG 387*7c478bd9Sstevel@tonic-gate fprintf(stderr, "mergeaddr: Call to the original" 388*7c478bd9Sstevel@tonic-gate " ND_MERGEADDR interface\n"); 389*7c478bd9Sstevel@tonic-gate #endif 390*7c478bd9Sstevel@tonic-gate stat = netdir_options(fdl->nconf, ND_MERGEADDR, 0, (char *)&ma); 391*7c478bd9Sstevel@tonic-gate } else { 392*7c478bd9Sstevel@tonic-gate /* 393*7c478bd9Sstevel@tonic-gate * (xprt)->xp_ltaddr contains portmap's port address. 394*7c478bd9Sstevel@tonic-gate * Overwrite this with actual application's port address 395*7c478bd9Sstevel@tonic-gate * before returning to the caller. 396*7c478bd9Sstevel@tonic-gate */ 397*7c478bd9Sstevel@tonic-gate char *s_uport, *uport; 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate /* Get the INET/INET6 address part from ma.s_uaddr */ 400*7c478bd9Sstevel@tonic-gate UADDR_PRT_INDX(ma.s_uaddr, s_uport); 401*7c478bd9Sstevel@tonic-gate *s_uport = '\0'; 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate /* Get the port info from uaddr */ 404*7c478bd9Sstevel@tonic-gate UADDR_PRT_INDX(uaddr, uport); 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate ma.m_uaddr = malloc(strlen(ma.s_uaddr) + strlen(uport) + 1); 407*7c478bd9Sstevel@tonic-gate if (ma.m_uaddr == NULL) { 408*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "mergeaddr: no memory!"); 409*7c478bd9Sstevel@tonic-gate free(ma.s_uaddr); 410*7c478bd9Sstevel@tonic-gate if (saddr == NULL) 411*7c478bd9Sstevel@tonic-gate free(ma.c_uaddr); 412*7c478bd9Sstevel@tonic-gate return (NULL); 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate /* Copy IP address into the Universal address holder */ 416*7c478bd9Sstevel@tonic-gate strcpy(ma.m_uaddr, ma.s_uaddr); 417*7c478bd9Sstevel@tonic-gate /* Append port info to the Universal address holder */ 418*7c478bd9Sstevel@tonic-gate strcat(ma.m_uaddr, uport); 419*7c478bd9Sstevel@tonic-gate free(ma.s_uaddr); 420*7c478bd9Sstevel@tonic-gate stat = 0; 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate #ifdef ND_DEBUG 423*7c478bd9Sstevel@tonic-gate fprintf(stderr, "mergeaddr: Just return the address which was" 424*7c478bd9Sstevel@tonic-gate " used for contacting us\n"); 425*7c478bd9Sstevel@tonic-gate #endif 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate if (saddr == NULL) { 428*7c478bd9Sstevel@tonic-gate free(ma.c_uaddr); 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate if (stat) { 431*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "netdir_merge failed for %s: %s", 432*7c478bd9Sstevel@tonic-gate fdl->nconf->nc_netid, netdir_sperror()); 433*7c478bd9Sstevel@tonic-gate return (NULL); 434*7c478bd9Sstevel@tonic-gate } 435*7c478bd9Sstevel@tonic-gate #ifdef ND_DEBUG 436*7c478bd9Sstevel@tonic-gate fprintf(stderr, "mergeaddr: uaddr = %s, merged uaddr = %s\n", 437*7c478bd9Sstevel@tonic-gate uaddr, ma.m_uaddr); 438*7c478bd9Sstevel@tonic-gate #endif 439*7c478bd9Sstevel@tonic-gate return (ma.m_uaddr); 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate /* 443*7c478bd9Sstevel@tonic-gate * Returns a netconf structure from its internal list. This 444*7c478bd9Sstevel@tonic-gate * structure should not be freed. 445*7c478bd9Sstevel@tonic-gate */ 446*7c478bd9Sstevel@tonic-gate struct netconfig * 447*7c478bd9Sstevel@tonic-gate rpcbind_get_conf(netid) 448*7c478bd9Sstevel@tonic-gate char *netid; 449*7c478bd9Sstevel@tonic-gate { 450*7c478bd9Sstevel@tonic-gate struct fdlist *fdl; 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate for (fdl = fdhead; fdl; fdl = fdl->next) 453*7c478bd9Sstevel@tonic-gate if (strcmp(fdl->nconf->nc_netid, netid) == 0) 454*7c478bd9Sstevel@tonic-gate break; 455*7c478bd9Sstevel@tonic-gate if (fdl == NULL) 456*7c478bd9Sstevel@tonic-gate return (NULL); 457*7c478bd9Sstevel@tonic-gate return (fdl->nconf); 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate #ifdef BIND_DEBUG 461*7c478bd9Sstevel@tonic-gate syslog(a, msg, b, c, d) 462*7c478bd9Sstevel@tonic-gate int a; 463*7c478bd9Sstevel@tonic-gate char *msg; 464*7c478bd9Sstevel@tonic-gate caddr_t b, c, d; 465*7c478bd9Sstevel@tonic-gate { 466*7c478bd9Sstevel@tonic-gate char buf[1024]; 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate sprintf(buf, msg, b, c, d); 469*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Syslog: %s\n", buf); 470*7c478bd9Sstevel@tonic-gate } 471*7c478bd9Sstevel@tonic-gate #endif 472