1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte #include <locale.h> 27*fcf3ce44SJohn Forte #include <stdio.h> 28*fcf3ce44SJohn Forte #include <string.h> 29*fcf3ce44SJohn Forte #include <memory.h> 30*fcf3ce44SJohn Forte #include <varargs.h> 31*fcf3ce44SJohn Forte #include <unistd.h> 32*fcf3ce44SJohn Forte #include <ctype.h> 33*fcf3ce44SJohn Forte #include <stdlib.h> 34*fcf3ce44SJohn Forte #include <signal.h> 35*fcf3ce44SJohn Forte #include <sys/param.h> 36*fcf3ce44SJohn Forte #include <rpc/rpc.h> 37*fcf3ce44SJohn Forte #include <errno.h> 38*fcf3ce44SJohn Forte #include <sys/stat.h> 39*fcf3ce44SJohn Forte #include <netdb.h> 40*fcf3ce44SJohn Forte #include <sys/pathconf.h> 41*fcf3ce44SJohn Forte #include <netdir.h> 42*fcf3ce44SJohn Forte #include <netconfig.h> 43*fcf3ce44SJohn Forte #include <sys/sockio.h> 44*fcf3ce44SJohn Forte #include <net/if.h> 45*fcf3ce44SJohn Forte #include <syslog.h> 46*fcf3ce44SJohn Forte #include <netinet/in.h> 47*fcf3ce44SJohn Forte #include <nfs/nfs_sec.h> 48*fcf3ce44SJohn Forte #include <strings.h> 49*fcf3ce44SJohn Forte #include <sys/nsctl/rdc_prot.h> 50*fcf3ce44SJohn Forte #include <nsctl.h> 51*fcf3ce44SJohn Forte 52*fcf3ce44SJohn Forte #include "librdc.h" 53*fcf3ce44SJohn Forte 54*fcf3ce44SJohn Forte #define MAXIFS 32 55*fcf3ce44SJohn Forte 56*fcf3ce44SJohn Forte /* number of transports to try */ 57*fcf3ce44SJohn Forte #define MNT_PREF_LISTLEN 2 58*fcf3ce44SJohn Forte #define FIRST_TRY 1 59*fcf3ce44SJohn Forte #define SECOND_TRY 2 60*fcf3ce44SJohn Forte 61*fcf3ce44SJohn Forte 62*fcf3ce44SJohn Forte int 63*fcf3ce44SJohn Forte Is_ipv6present(void) 64*fcf3ce44SJohn Forte { 65*fcf3ce44SJohn Forte #ifdef AF_INET6 66*fcf3ce44SJohn Forte int sock; 67*fcf3ce44SJohn Forte struct lifnum lifn; 68*fcf3ce44SJohn Forte 69*fcf3ce44SJohn Forte sock = socket(AF_INET6, SOCK_DGRAM, 0); 70*fcf3ce44SJohn Forte if (sock < 0) 71*fcf3ce44SJohn Forte return (0); 72*fcf3ce44SJohn Forte 73*fcf3ce44SJohn Forte lifn.lifn_family = AF_INET6; 74*fcf3ce44SJohn Forte lifn.lifn_flags = 0; 75*fcf3ce44SJohn Forte if (ioctl(sock, SIOCGLIFNUM, (char *)&lifn) < 0) { 76*fcf3ce44SJohn Forte close(sock); 77*fcf3ce44SJohn Forte return (0); 78*fcf3ce44SJohn Forte } 79*fcf3ce44SJohn Forte close(sock); 80*fcf3ce44SJohn Forte if (lifn.lifn_count == 0) 81*fcf3ce44SJohn Forte return (0); 82*fcf3ce44SJohn Forte return (1); 83*fcf3ce44SJohn Forte #else 84*fcf3ce44SJohn Forte return (0); 85*fcf3ce44SJohn Forte #endif 86*fcf3ce44SJohn Forte } 87*fcf3ce44SJohn Forte 88*fcf3ce44SJohn Forte /* 89*fcf3ce44SJohn Forte * The following is stolen from autod_nfs.c 90*fcf3ce44SJohn Forte */ 91*fcf3ce44SJohn Forte static void 92*fcf3ce44SJohn Forte getmyaddrs(struct ifconf *ifc) 93*fcf3ce44SJohn Forte { 94*fcf3ce44SJohn Forte int sock; 95*fcf3ce44SJohn Forte int numifs; 96*fcf3ce44SJohn Forte char *buf; 97*fcf3ce44SJohn Forte int family; 98*fcf3ce44SJohn Forte 99*fcf3ce44SJohn Forte ifc->ifc_buf = NULL; 100*fcf3ce44SJohn Forte ifc->ifc_len = 0; 101*fcf3ce44SJohn Forte 102*fcf3ce44SJohn Forte #ifdef AF_INET6 103*fcf3ce44SJohn Forte family = AF_INET6; 104*fcf3ce44SJohn Forte #else 105*fcf3ce44SJohn Forte family = AF_INET; 106*fcf3ce44SJohn Forte #endif 107*fcf3ce44SJohn Forte if ((sock = socket(family, SOCK_DGRAM, 0)) < 0) { 108*fcf3ce44SJohn Forte #ifdef DEBUG 109*fcf3ce44SJohn Forte perror("getmyaddrs(): socket"); 110*fcf3ce44SJohn Forte #endif 111*fcf3ce44SJohn Forte return; 112*fcf3ce44SJohn Forte } 113*fcf3ce44SJohn Forte 114*fcf3ce44SJohn Forte if (ioctl(sock, SIOCGIFNUM, (char *)&numifs) < 0) { 115*fcf3ce44SJohn Forte #ifdef DEBUG 116*fcf3ce44SJohn Forte perror("getmyaddrs(): SIOCGIFNUM"); 117*fcf3ce44SJohn Forte #endif 118*fcf3ce44SJohn Forte numifs = MAXIFS; 119*fcf3ce44SJohn Forte } 120*fcf3ce44SJohn Forte 121*fcf3ce44SJohn Forte buf = (char *)malloc(numifs * sizeof (struct ifreq)); 122*fcf3ce44SJohn Forte if (buf == NULL) { 123*fcf3ce44SJohn Forte #ifdef DEBUG 124*fcf3ce44SJohn Forte fprintf(stderr, "getmyaddrs(): malloc failed\n"); 125*fcf3ce44SJohn Forte #endif 126*fcf3ce44SJohn Forte (void) close(sock); 127*fcf3ce44SJohn Forte return; 128*fcf3ce44SJohn Forte } 129*fcf3ce44SJohn Forte 130*fcf3ce44SJohn Forte ifc->ifc_buf = buf; 131*fcf3ce44SJohn Forte ifc->ifc_len = numifs * sizeof (struct ifreq); 132*fcf3ce44SJohn Forte 133*fcf3ce44SJohn Forte if (ioctl(sock, SIOCGIFCONF, (char *)ifc) < 0) { 134*fcf3ce44SJohn Forte #ifdef DEBUG 135*fcf3ce44SJohn Forte perror("getmyaddrs(): SIOCGIFCONF"); 136*fcf3ce44SJohn Forte #else 137*fcf3ce44SJohn Forte ; 138*fcf3ce44SJohn Forte /*EMPTY*/ 139*fcf3ce44SJohn Forte #endif 140*fcf3ce44SJohn Forte } 141*fcf3ce44SJohn Forte 142*fcf3ce44SJohn Forte (void) close(sock); 143*fcf3ce44SJohn Forte } 144*fcf3ce44SJohn Forte 145*fcf3ce44SJohn Forte int 146*fcf3ce44SJohn Forte self_check(char *hostname) 147*fcf3ce44SJohn Forte { 148*fcf3ce44SJohn Forte int n; 149*fcf3ce44SJohn Forte struct sockaddr_in *s1, *s2; 150*fcf3ce44SJohn Forte struct ifreq *ifr; 151*fcf3ce44SJohn Forte struct nd_hostserv hs; 152*fcf3ce44SJohn Forte struct nd_addrlist *retaddrs; 153*fcf3ce44SJohn Forte struct netconfig *nconfp; 154*fcf3ce44SJohn Forte struct ifconf *ifc; 155*fcf3ce44SJohn Forte int retval; 156*fcf3ce44SJohn Forte 157*fcf3ce44SJohn Forte ifc = malloc(sizeof (struct ifconf)); 158*fcf3ce44SJohn Forte if (ifc == NULL) 159*fcf3ce44SJohn Forte return (0); 160*fcf3ce44SJohn Forte memset((char *)ifc, 0, sizeof (struct ifconf)); 161*fcf3ce44SJohn Forte getmyaddrs(ifc); 162*fcf3ce44SJohn Forte /* 163*fcf3ce44SJohn Forte * Get the IP address for hostname 164*fcf3ce44SJohn Forte */ 165*fcf3ce44SJohn Forte nconfp = getnetconfigent("udp"); 166*fcf3ce44SJohn Forte if (nconfp == NULL) { 167*fcf3ce44SJohn Forte #ifdef DEBUG 168*fcf3ce44SJohn Forte fprintf(stderr, "self_check(): getnetconfigent failed\n"); 169*fcf3ce44SJohn Forte #endif 170*fcf3ce44SJohn Forte retval = 0; 171*fcf3ce44SJohn Forte goto out; 172*fcf3ce44SJohn Forte } 173*fcf3ce44SJohn Forte hs.h_host = hostname; 174*fcf3ce44SJohn Forte hs.h_serv = "rpcbind"; 175*fcf3ce44SJohn Forte if (netdir_getbyname(nconfp, &hs, &retaddrs) != ND_OK) { 176*fcf3ce44SJohn Forte freenetconfigent(nconfp); 177*fcf3ce44SJohn Forte retval = 0; 178*fcf3ce44SJohn Forte goto out; 179*fcf3ce44SJohn Forte } 180*fcf3ce44SJohn Forte freenetconfigent(nconfp); 181*fcf3ce44SJohn Forte /* LINTED pointer alignment */ 182*fcf3ce44SJohn Forte s1 = (struct sockaddr_in *)retaddrs->n_addrs->buf; 183*fcf3ce44SJohn Forte 184*fcf3ce44SJohn Forte /* 185*fcf3ce44SJohn Forte * Now compare it against the list of 186*fcf3ce44SJohn Forte * addresses for the interfaces on this 187*fcf3ce44SJohn Forte * host. 188*fcf3ce44SJohn Forte */ 189*fcf3ce44SJohn Forte ifr = ifc->ifc_req; 190*fcf3ce44SJohn Forte n = ifc->ifc_len / sizeof (struct ifreq); 191*fcf3ce44SJohn Forte s2 = NULL; 192*fcf3ce44SJohn Forte for (; n > 0; n--, ifr++) { 193*fcf3ce44SJohn Forte if (ifr->ifr_addr.sa_family != AF_INET) 194*fcf3ce44SJohn Forte continue; 195*fcf3ce44SJohn Forte 196*fcf3ce44SJohn Forte /* LINTED pointer alignment */ 197*fcf3ce44SJohn Forte s2 = (struct sockaddr_in *)&ifr->ifr_addr; 198*fcf3ce44SJohn Forte 199*fcf3ce44SJohn Forte if (memcmp((char *)&s2->sin_addr, 200*fcf3ce44SJohn Forte (char *)&s1->sin_addr, sizeof (s1->sin_addr)) == 0) { 201*fcf3ce44SJohn Forte netdir_free((void *)retaddrs, ND_ADDRLIST); 202*fcf3ce44SJohn Forte retval = 1; 203*fcf3ce44SJohn Forte goto out; /* it's me */ 204*fcf3ce44SJohn Forte } 205*fcf3ce44SJohn Forte } 206*fcf3ce44SJohn Forte netdir_free((void *)retaddrs, ND_ADDRLIST); 207*fcf3ce44SJohn Forte retval = 0; 208*fcf3ce44SJohn Forte 209*fcf3ce44SJohn Forte out: 210*fcf3ce44SJohn Forte if (ifc->ifc_buf != NULL) 211*fcf3ce44SJohn Forte free(ifc->ifc_buf); 212*fcf3ce44SJohn Forte free(ifc); 213*fcf3ce44SJohn Forte return (retval); 214*fcf3ce44SJohn Forte } 215*fcf3ce44SJohn Forte 216*fcf3ce44SJohn Forte 217*fcf3ce44SJohn Forte int 218*fcf3ce44SJohn Forte convert_nconf_to_knconf(struct netconfig *nconf, struct knetconfig *knconf) 219*fcf3ce44SJohn Forte { 220*fcf3ce44SJohn Forte struct stat sb; 221*fcf3ce44SJohn Forte 222*fcf3ce44SJohn Forte if (stat(nconf->nc_device, &sb) < 0) { 223*fcf3ce44SJohn Forte (void) syslog(LOG_ERR, "can't find device for transport %s\n", 224*fcf3ce44SJohn Forte nconf->nc_device); 225*fcf3ce44SJohn Forte return (-1); 226*fcf3ce44SJohn Forte } 227*fcf3ce44SJohn Forte #ifdef DEBUG_ADDR 228*fcf3ce44SJohn Forte printf("lib knconf %x %s %s %x\n", nconf->nc_semantics, 229*fcf3ce44SJohn Forte nconf->nc_protofmly, nconf->nc_proto, sb.st_rdev); 230*fcf3ce44SJohn Forte #endif 231*fcf3ce44SJohn Forte 232*fcf3ce44SJohn Forte knconf->knc_semantics = nconf->nc_semantics; 233*fcf3ce44SJohn Forte knconf->knc_protofmly = nconf->nc_protofmly; 234*fcf3ce44SJohn Forte knconf->knc_proto = nconf->nc_proto; 235*fcf3ce44SJohn Forte knconf->knc_rdev = sb.st_rdev; 236*fcf3ce44SJohn Forte 237*fcf3ce44SJohn Forte return (0); 238*fcf3ce44SJohn Forte } 239*fcf3ce44SJohn Forte 240*fcf3ce44SJohn Forte struct hostent * 241*fcf3ce44SJohn Forte gethost_byname(const char *name) 242*fcf3ce44SJohn Forte { 243*fcf3ce44SJohn Forte int errnum; 244*fcf3ce44SJohn Forte #ifdef AF_INET6 245*fcf3ce44SJohn Forte return (getipnodebyname(name, AF_INET6, AI_DEFAULT, &errnum)); 246*fcf3ce44SJohn Forte #else /* !AF_INET6 */ 247*fcf3ce44SJohn Forte return (gethostbyname(name)); 248*fcf3ce44SJohn Forte #endif /* AF_INET6 */ 249*fcf3ce44SJohn Forte } 250*fcf3ce44SJohn Forte 251*fcf3ce44SJohn Forte int 252*fcf3ce44SJohn Forte gethost_netaddrs(char *fromhost, char *tohost, 253*fcf3ce44SJohn Forte char *fromnetaddr, char *tonetaddr) 254*fcf3ce44SJohn Forte { 255*fcf3ce44SJohn Forte struct hostent *host; 256*fcf3ce44SJohn Forte int j; 257*fcf3ce44SJohn Forte int errnum; 258*fcf3ce44SJohn Forte 259*fcf3ce44SJohn Forte #ifdef AF_INET6 260*fcf3ce44SJohn Forte host = getipnodebyname(fromhost, AF_INET6, AI_DEFAULT, &errnum); 261*fcf3ce44SJohn Forte if (host == NULL) { 262*fcf3ce44SJohn Forte #ifdef DEBUG 263*fcf3ce44SJohn Forte (void) fprintf(stderr, dgettext("sndr", 264*fcf3ce44SJohn Forte "Could not find host %s"), fromhost); 265*fcf3ce44SJohn Forte #endif 266*fcf3ce44SJohn Forte return (-1); 267*fcf3ce44SJohn Forte } 268*fcf3ce44SJohn Forte for (j = 0; j < host->h_length; j++) 269*fcf3ce44SJohn Forte fromnetaddr[j] = host->h_addr[j]; 270*fcf3ce44SJohn Forte freehostent(host); 271*fcf3ce44SJohn Forte #else /* !AF_INET6 */ 272*fcf3ce44SJohn Forte host = gethostbyname(fromhost); 273*fcf3ce44SJohn Forte if (host == NULL) { 274*fcf3ce44SJohn Forte #ifdef DEBUG 275*fcf3ce44SJohn Forte (void) fprintf(stderr, dgettext("sndr", 276*fcf3ce44SJohn Forte "Could not find host %s"), fromhost); 277*fcf3ce44SJohn Forte #endif 278*fcf3ce44SJohn Forte return (-1); 279*fcf3ce44SJohn Forte } 280*fcf3ce44SJohn Forte 281*fcf3ce44SJohn Forte if (host->h_length < 4) { 282*fcf3ce44SJohn Forte #ifdef DEBUG 283*fcf3ce44SJohn Forte fprintf(stderr, "host->h_length(%d) < 4!\n", host->h_length); 284*fcf3ce44SJohn Forte #endif 285*fcf3ce44SJohn Forte return (-1); 286*fcf3ce44SJohn Forte } 287*fcf3ce44SJohn Forte 288*fcf3ce44SJohn Forte for (j = 0; j < host->h_length; j++) 289*fcf3ce44SJohn Forte fromnetaddr[j] = host->h_addr[j]; 290*fcf3ce44SJohn Forte #endif /* AF_INET6 */ 291*fcf3ce44SJohn Forte 292*fcf3ce44SJohn Forte #ifdef AF_INET6 293*fcf3ce44SJohn Forte host = getipnodebyname(tohost, AF_INET6, AI_DEFAULT, &errnum); 294*fcf3ce44SJohn Forte if (host == NULL) { 295*fcf3ce44SJohn Forte #ifdef DEBUG 296*fcf3ce44SJohn Forte (void) fprintf(stderr, dgettext("sndr", 297*fcf3ce44SJohn Forte "Could not find host %s"), tohost); 298*fcf3ce44SJohn Forte #endif 299*fcf3ce44SJohn Forte return (-1); 300*fcf3ce44SJohn Forte } 301*fcf3ce44SJohn Forte for (j = 0; j < host->h_length; j++) 302*fcf3ce44SJohn Forte tonetaddr[j] = host->h_addr[j]; 303*fcf3ce44SJohn Forte freehostent(host); 304*fcf3ce44SJohn Forte #else /* !AF_INET6 */ 305*fcf3ce44SJohn Forte host = gethostbyname(tohost); 306*fcf3ce44SJohn Forte if (host == NULL) { 307*fcf3ce44SJohn Forte #ifdef DEBUG 308*fcf3ce44SJohn Forte (void) fprintf(stderr, dgettext("sndr", 309*fcf3ce44SJohn Forte "Could not find host %s"), tohost); 310*fcf3ce44SJohn Forte #endif 311*fcf3ce44SJohn Forte return (-1); 312*fcf3ce44SJohn Forte } 313*fcf3ce44SJohn Forte 314*fcf3ce44SJohn Forte if (host->h_length < 4) { 315*fcf3ce44SJohn Forte #ifdef DEBUG 316*fcf3ce44SJohn Forte fprintf(stderr, "host->h_length(%d) < 4!\n", host->h_length); 317*fcf3ce44SJohn Forte #endif 318*fcf3ce44SJohn Forte return (-1); 319*fcf3ce44SJohn Forte } 320*fcf3ce44SJohn Forte 321*fcf3ce44SJohn Forte for (j = 0; j < host->h_length; j++) 322*fcf3ce44SJohn Forte tonetaddr[j] = host->h_addr[j]; 323*fcf3ce44SJohn Forte #endif /* AF_INET6 */ 324*fcf3ce44SJohn Forte return (0); 325*fcf3ce44SJohn Forte } 326*fcf3ce44SJohn Forte 327*fcf3ce44SJohn Forte /* 328*fcf3ce44SJohn Forte * Get the network address on "hostname" for program "prog" 329*fcf3ce44SJohn Forte * with version "vers" by using the nconf configuration data 330*fcf3ce44SJohn Forte * passed in. 331*fcf3ce44SJohn Forte * 332*fcf3ce44SJohn Forte * If the address of a netconfig pointer is null then 333*fcf3ce44SJohn Forte * information is not sufficient and no netbuf will be returned. 334*fcf3ce44SJohn Forte * 335*fcf3ce44SJohn Forte * Finally, ping the null procedure of that service. 336*fcf3ce44SJohn Forte * 337*fcf3ce44SJohn Forte */ 338*fcf3ce44SJohn Forte static struct netbuf * 339*fcf3ce44SJohn Forte get_the_addr(char *hostname, ulong_t prog, ulong_t vers, 340*fcf3ce44SJohn Forte struct netconfig *nconf, ushort_t port, struct t_info *tinfo, 341*fcf3ce44SJohn Forte int portmap) 342*fcf3ce44SJohn Forte { 343*fcf3ce44SJohn Forte struct netbuf *nb = NULL; 344*fcf3ce44SJohn Forte struct t_bind *tbind = NULL; 345*fcf3ce44SJohn Forte CLIENT *cl = NULL; 346*fcf3ce44SJohn Forte struct timeval tv; 347*fcf3ce44SJohn Forte int fd = -1; 348*fcf3ce44SJohn Forte AUTH *ah = NULL; 349*fcf3ce44SJohn Forte 350*fcf3ce44SJohn Forte if (nconf == NULL) 351*fcf3ce44SJohn Forte return (NULL); 352*fcf3ce44SJohn Forte 353*fcf3ce44SJohn Forte if ((fd = t_open(nconf->nc_device, O_RDWR, tinfo)) == -1) 354*fcf3ce44SJohn Forte goto done; 355*fcf3ce44SJohn Forte 356*fcf3ce44SJohn Forte /* LINTED pointer alignment */ 357*fcf3ce44SJohn Forte if ((tbind = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR)) == NULL) 358*fcf3ce44SJohn Forte goto done; 359*fcf3ce44SJohn Forte 360*fcf3ce44SJohn Forte if (portmap) { /* contact rpcbind */ 361*fcf3ce44SJohn Forte if (rpcb_getaddr(prog, vers, nconf, &tbind->addr, 362*fcf3ce44SJohn Forte hostname) == FALSE) { 363*fcf3ce44SJohn Forte goto done; 364*fcf3ce44SJohn Forte } 365*fcf3ce44SJohn Forte 366*fcf3ce44SJohn Forte if (port) { 367*fcf3ce44SJohn Forte if (strcmp(nconf->nc_protofmly, NC_INET) == 0) 368*fcf3ce44SJohn Forte /* LINTED pointer alignment */ 369*fcf3ce44SJohn Forte ((struct sockaddr_in *)tbind->addr.buf)->sin_port 370*fcf3ce44SJohn Forte = port; 371*fcf3ce44SJohn Forte #ifdef NC_INET6 372*fcf3ce44SJohn Forte else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) 373*fcf3ce44SJohn Forte /* LINTED pointer alignment */ 374*fcf3ce44SJohn Forte ((struct sockaddr_in6 *)tbind->addr.buf)->sin6_port 375*fcf3ce44SJohn Forte = port; 376*fcf3ce44SJohn Forte #endif 377*fcf3ce44SJohn Forte } 378*fcf3ce44SJohn Forte 379*fcf3ce44SJohn Forte /* Simon -- we never use the client we create?! */ 380*fcf3ce44SJohn Forte cl = clnt_tli_create(fd, nconf, &tbind->addr, prog, vers, 0, 0); 381*fcf3ce44SJohn Forte if (cl == NULL) 382*fcf3ce44SJohn Forte goto done; 383*fcf3ce44SJohn Forte 384*fcf3ce44SJohn Forte ah = authsys_create_default(); 385*fcf3ce44SJohn Forte if (ah != NULL) 386*fcf3ce44SJohn Forte cl->cl_auth = ah; 387*fcf3ce44SJohn Forte 388*fcf3ce44SJohn Forte tv.tv_sec = 5; 389*fcf3ce44SJohn Forte tv.tv_usec = 0; 390*fcf3ce44SJohn Forte 391*fcf3ce44SJohn Forte (void) clnt_control(cl, CLSET_TIMEOUT, (char *)&tv); 392*fcf3ce44SJohn Forte } else { /* create our own address and skip rpcbind */ 393*fcf3ce44SJohn Forte struct netbuf *nb; 394*fcf3ce44SJohn Forte struct hostent *hp; 395*fcf3ce44SJohn Forte int j; 396*fcf3ce44SJohn Forte int errnum; 397*fcf3ce44SJohn Forte unsigned short family; 398*fcf3ce44SJohn Forte nb = &(tbind->addr); 399*fcf3ce44SJohn Forte 400*fcf3ce44SJohn Forte #ifdef AF_INET6 401*fcf3ce44SJohn Forte if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) { 402*fcf3ce44SJohn Forte hp = getipnodebyname(hostname, AF_INET6, 0, &errnum); 403*fcf3ce44SJohn Forte family = AF_INET6; 404*fcf3ce44SJohn Forte nb->len = nb->maxlen = sizeof (struct sockaddr_in6); 405*fcf3ce44SJohn Forte } else { 406*fcf3ce44SJohn Forte hp = getipnodebyname(hostname, AF_INET, 0, &errnum); 407*fcf3ce44SJohn Forte family = AF_INET; 408*fcf3ce44SJohn Forte nb->len = nb->maxlen = sizeof (struct sockaddr_in); 409*fcf3ce44SJohn Forte } 410*fcf3ce44SJohn Forte if (hp == NULL) { 411*fcf3ce44SJohn Forte #ifdef DEBUG_ADDR 412*fcf3ce44SJohn Forte (void) fprintf(stderr, dgettext("sndr", 413*fcf3ce44SJohn Forte "Could not find host %s\n"), hostname); 414*fcf3ce44SJohn Forte #endif 415*fcf3ce44SJohn Forte goto done; 416*fcf3ce44SJohn Forte } 417*fcf3ce44SJohn Forte nb->buf = (char *)calloc(1, nb->maxlen); 418*fcf3ce44SJohn Forte if (nb->buf == NULL) { 419*fcf3ce44SJohn Forte (void) printf(dgettext("sndr", "no memory\n")); 420*fcf3ce44SJohn Forte goto done; 421*fcf3ce44SJohn Forte } 422*fcf3ce44SJohn Forte 423*fcf3ce44SJohn Forte if (family == AF_INET) { 424*fcf3ce44SJohn Forte for (j = 0; j < hp->h_length; j++) 425*fcf3ce44SJohn Forte nb->buf[j+4] = hp->h_addr[j]; 426*fcf3ce44SJohn Forte /* LINTED pointer alignment */ 427*fcf3ce44SJohn Forte ((struct sockaddr_in *)(nb->buf))->sin_port = port; 428*fcf3ce44SJohn Forte /* LINTED pointer alignment */ 429*fcf3ce44SJohn Forte ((struct sockaddr_in *)(nb->buf))->sin_family = AF_INET; 430*fcf3ce44SJohn Forte } else { 431*fcf3ce44SJohn Forte for (j = 0; j < hp->h_length; j++) 432*fcf3ce44SJohn Forte nb->buf[j+8] = hp->h_addr[j]; 433*fcf3ce44SJohn Forte /* LINTED pointer alignment */ 434*fcf3ce44SJohn Forte ((struct sockaddr_in6 *)(nb->buf))->sin6_port = port; 435*fcf3ce44SJohn Forte /* LINTED pointer alignment */ 436*fcf3ce44SJohn Forte ((struct sockaddr_in6 *)(nb->buf))->sin6_family = 437*fcf3ce44SJohn Forte AF_INET6; 438*fcf3ce44SJohn Forte } 439*fcf3ce44SJohn Forte freehostent(hp); 440*fcf3ce44SJohn Forte #else 441*fcf3ce44SJohn Forte hp = gethostbyname(hostname); 442*fcf3ce44SJohn Forte if (hp == NULL) { 443*fcf3ce44SJohn Forte #ifdef DEBUG 444*fcf3ce44SJohn Forte (void) fprintf(stderr, dgettext("sndr", 445*fcf3ce44SJohn Forte "Could not find host %s"), hostname); 446*fcf3ce44SJohn Forte #endif 447*fcf3ce44SJohn Forte goto done; 448*fcf3ce44SJohn Forte } 449*fcf3ce44SJohn Forte 450*fcf3ce44SJohn Forte nb->len = nb->maxlen = sizeof (struct sockaddr_in); 451*fcf3ce44SJohn Forte nb->buf = (char *)calloc(1, nb->maxlen); 452*fcf3ce44SJohn Forte if (nb->buf == NULL) { 453*fcf3ce44SJohn Forte (void) printf(dgettext("sndr", "no memory\n")); 454*fcf3ce44SJohn Forte free(nb); 455*fcf3ce44SJohn Forte nb = NULL; 456*fcf3ce44SJohn Forte goto done; 457*fcf3ce44SJohn Forte } 458*fcf3ce44SJohn Forte 459*fcf3ce44SJohn Forte for (j = 0; j < hp->h_length; j++) 460*fcf3ce44SJohn Forte nb->buf[j+4] = hp->h_addr[j]; 461*fcf3ce44SJohn Forte 462*fcf3ce44SJohn Forte if (hp->h_addrtype == AF_INET) { 463*fcf3ce44SJohn Forte ((struct sockaddr_in *)(nb->buf))->sin_port = port; 464*fcf3ce44SJohn Forte ((struct sockaddr_in *)(nb->buf))->sin_family = AF_INET; 465*fcf3ce44SJohn Forte } 466*fcf3ce44SJohn Forte #endif 467*fcf3ce44SJohn Forte } 468*fcf3ce44SJohn Forte 469*fcf3ce44SJohn Forte /* 470*fcf3ce44SJohn Forte * Make a copy of the netbuf to return 471*fcf3ce44SJohn Forte */ 472*fcf3ce44SJohn Forte nb = (struct netbuf *)calloc(1, sizeof (*nb)); 473*fcf3ce44SJohn Forte if (nb == NULL) { 474*fcf3ce44SJohn Forte (void) printf(dgettext("sndr", "no memory\n")); 475*fcf3ce44SJohn Forte goto done; 476*fcf3ce44SJohn Forte } 477*fcf3ce44SJohn Forte 478*fcf3ce44SJohn Forte *nb = tbind->addr; /* structure copy */ 479*fcf3ce44SJohn Forte 480*fcf3ce44SJohn Forte nb->buf = (char *)calloc(1, nb->maxlen); 481*fcf3ce44SJohn Forte if (nb->buf == NULL) { 482*fcf3ce44SJohn Forte (void) printf(dgettext("sndr", "no memory\n")); 483*fcf3ce44SJohn Forte free(nb); 484*fcf3ce44SJohn Forte nb = NULL; 485*fcf3ce44SJohn Forte goto done; 486*fcf3ce44SJohn Forte } 487*fcf3ce44SJohn Forte 488*fcf3ce44SJohn Forte (void) memcpy(nb->buf, tbind->addr.buf, tbind->addr.len); 489*fcf3ce44SJohn Forte 490*fcf3ce44SJohn Forte done: 491*fcf3ce44SJohn Forte if (cl) { 492*fcf3ce44SJohn Forte if (ah != NULL) { 493*fcf3ce44SJohn Forte AUTH_DESTROY(cl->cl_auth); 494*fcf3ce44SJohn Forte cl->cl_auth = NULL; 495*fcf3ce44SJohn Forte } 496*fcf3ce44SJohn Forte 497*fcf3ce44SJohn Forte clnt_destroy(cl); 498*fcf3ce44SJohn Forte cl = NULL; 499*fcf3ce44SJohn Forte } 500*fcf3ce44SJohn Forte 501*fcf3ce44SJohn Forte if (tbind) { 502*fcf3ce44SJohn Forte t_free((char *)tbind, T_BIND); 503*fcf3ce44SJohn Forte tbind = NULL; 504*fcf3ce44SJohn Forte } 505*fcf3ce44SJohn Forte 506*fcf3ce44SJohn Forte if (fd >= 0) 507*fcf3ce44SJohn Forte (void) t_close(fd); 508*fcf3ce44SJohn Forte return (nb); 509*fcf3ce44SJohn Forte } 510*fcf3ce44SJohn Forte 511*fcf3ce44SJohn Forte /* 512*fcf3ce44SJohn Forte * Get a network address on "hostname" for program "prog" 513*fcf3ce44SJohn Forte * with version "vers". If the port number is specified (non zero) 514*fcf3ce44SJohn Forte * then try for a TCP/UDP transport and set the port number of the 515*fcf3ce44SJohn Forte * resulting IP address. 516*fcf3ce44SJohn Forte * 517*fcf3ce44SJohn Forte * If the address of a netconfig pointer was passed and 518*fcf3ce44SJohn Forte * if it's not null, use it as the netconfig otherwise 519*fcf3ce44SJohn Forte * assign the address of the netconfig that was used to 520*fcf3ce44SJohn Forte * establish contact with the service. 521*fcf3ce44SJohn Forte * If portmap is false, we return a similiar address and we do not 522*fcf3ce44SJohn Forte * contact rpcbind 523*fcf3ce44SJohn Forte * 524*fcf3ce44SJohn Forte */ 525*fcf3ce44SJohn Forte struct netbuf * 526*fcf3ce44SJohn Forte get_addr(char *hostname, ulong_t prog, ulong_t vers, struct netconfig **nconfp, 527*fcf3ce44SJohn Forte char *proto, char *srvport, struct t_info *tinfo, int portmap) 528*fcf3ce44SJohn Forte { 529*fcf3ce44SJohn Forte struct netbuf *nb = NULL; 530*fcf3ce44SJohn Forte struct netconfig *nconf = NULL; 531*fcf3ce44SJohn Forte NCONF_HANDLE *nc = NULL; 532*fcf3ce44SJohn Forte int nthtry = FIRST_TRY; 533*fcf3ce44SJohn Forte struct servent *svp; 534*fcf3ce44SJohn Forte ushort_t port; 535*fcf3ce44SJohn Forte 536*fcf3ce44SJohn Forte /* 537*fcf3ce44SJohn Forte * First lets get the requested port 538*fcf3ce44SJohn Forte */ 539*fcf3ce44SJohn Forte 540*fcf3ce44SJohn Forte if ((svp = getservbyname(srvport, proto)) == NULL) 541*fcf3ce44SJohn Forte goto done; 542*fcf3ce44SJohn Forte port = svp->s_port; 543*fcf3ce44SJohn Forte /* 544*fcf3ce44SJohn Forte * No nconf passed in. 545*fcf3ce44SJohn Forte * 546*fcf3ce44SJohn Forte * Try to get a nconf from /etc/netconfig filtered by 547*fcf3ce44SJohn Forte * the NETPATH environment variable. 548*fcf3ce44SJohn Forte * First search for COTS, second for CLTS unless proto 549*fcf3ce44SJohn Forte * is specified. When we retry, we reset the 550*fcf3ce44SJohn Forte * netconfig list so that we would search the whole list 551*fcf3ce44SJohn Forte * all over again. 552*fcf3ce44SJohn Forte */ 553*fcf3ce44SJohn Forte if ((nc = setnetpath()) == NULL) 554*fcf3ce44SJohn Forte goto done; 555*fcf3ce44SJohn Forte 556*fcf3ce44SJohn Forte /* 557*fcf3ce44SJohn Forte * If proto is specified, then only search for the match, 558*fcf3ce44SJohn Forte * otherwise try COTS first, if failed, try CLTS. 559*fcf3ce44SJohn Forte */ 560*fcf3ce44SJohn Forte if (proto) { 561*fcf3ce44SJohn Forte while (nconf = getnetpath(nc)) { 562*fcf3ce44SJohn Forte if (strcmp(nconf->nc_netid, proto) == 0) { 563*fcf3ce44SJohn Forte /* 564*fcf3ce44SJohn Forte * If the port number is specified then TCP/UDP 565*fcf3ce44SJohn Forte * is needed. Otherwise any cots/clts will do. 566*fcf3ce44SJohn Forte */ 567*fcf3ce44SJohn Forte if (port == 0) 568*fcf3ce44SJohn Forte break; 569*fcf3ce44SJohn Forte 570*fcf3ce44SJohn Forte if ((strcmp(nconf->nc_protofmly, NC_INET) == 0 571*fcf3ce44SJohn Forte #ifdef NC_INET6 572*fcf3ce44SJohn Forte /* CSTYLED */ 573*fcf3ce44SJohn Forte || strcmp(nconf->nc_protofmly, NC_INET6) == 0 574*fcf3ce44SJohn Forte #endif 575*fcf3ce44SJohn Forte /* CSTYLED */ 576*fcf3ce44SJohn Forte ) && 577*fcf3ce44SJohn Forte (strcmp(nconf->nc_proto, NC_TCP) == 0 || 578*fcf3ce44SJohn Forte strcmp(nconf->nc_proto, NC_UDP) == 0)) 579*fcf3ce44SJohn Forte break; 580*fcf3ce44SJohn Forte else { 581*fcf3ce44SJohn Forte nconf = NULL; 582*fcf3ce44SJohn Forte break; 583*fcf3ce44SJohn Forte } 584*fcf3ce44SJohn Forte } 585*fcf3ce44SJohn Forte } 586*fcf3ce44SJohn Forte if (nconf == NULL) 587*fcf3ce44SJohn Forte goto done; 588*fcf3ce44SJohn Forte if ((nb = get_the_addr(hostname, prog, vers, nconf, port, 589*fcf3ce44SJohn Forte tinfo, portmap)) == NULL) { 590*fcf3ce44SJohn Forte goto done; 591*fcf3ce44SJohn Forte } 592*fcf3ce44SJohn Forte } else { 593*fcf3ce44SJohn Forte retry: 594*fcf3ce44SJohn Forte while (nconf = getnetpath(nc)) { 595*fcf3ce44SJohn Forte if (nconf->nc_flag & NC_VISIBLE) { 596*fcf3ce44SJohn Forte if (nthtry == FIRST_TRY) { 597*fcf3ce44SJohn Forte if ((nconf->nc_semantics == NC_TPI_COTS_ORD) || 598*fcf3ce44SJohn Forte (nconf->nc_semantics == NC_TPI_COTS)) { 599*fcf3ce44SJohn Forte if (port == 0) 600*fcf3ce44SJohn Forte break; 601*fcf3ce44SJohn Forte if ((strcmp(nconf->nc_protofmly, 602*fcf3ce44SJohn Forte NC_INET) == 0 603*fcf3ce44SJohn Forte #ifdef NC_INET6 604*fcf3ce44SJohn Forte /* CSTYLED */ 605*fcf3ce44SJohn Forte || strcmp(nconf->nc_protofmly, 606*fcf3ce44SJohn Forte NC_INET6) == 0 607*fcf3ce44SJohn Forte #endif 608*fcf3ce44SJohn Forte /* CSTYLED */ 609*fcf3ce44SJohn Forte ) && 610*fcf3ce44SJohn Forte (strcmp(nconf->nc_proto, NC_TCP) == 0)) 611*fcf3ce44SJohn Forte break; 612*fcf3ce44SJohn Forte } 613*fcf3ce44SJohn Forte } 614*fcf3ce44SJohn Forte } 615*fcf3ce44SJohn Forte } /* while */ 616*fcf3ce44SJohn Forte if (nconf == NULL) { 617*fcf3ce44SJohn Forte if (++nthtry <= MNT_PREF_LISTLEN) { 618*fcf3ce44SJohn Forte endnetpath(nc); 619*fcf3ce44SJohn Forte if ((nc = setnetpath()) == NULL) 620*fcf3ce44SJohn Forte goto done; 621*fcf3ce44SJohn Forte goto retry; 622*fcf3ce44SJohn Forte } else 623*fcf3ce44SJohn Forte goto done; 624*fcf3ce44SJohn Forte } else { 625*fcf3ce44SJohn Forte if ((nb = get_the_addr(hostname, prog, vers, nconf, 626*fcf3ce44SJohn Forte port, tinfo, portmap)) == NULL) { 627*fcf3ce44SJohn Forte /* 628*fcf3ce44SJohn Forte * Continue the same search path in the 629*fcf3ce44SJohn Forte * netconfig db until no more matched 630*fcf3ce44SJohn Forte * nconf (nconf == NULL). 631*fcf3ce44SJohn Forte */ 632*fcf3ce44SJohn Forte goto retry; 633*fcf3ce44SJohn Forte } 634*fcf3ce44SJohn Forte #ifdef AF_INET6 635*fcf3ce44SJohn Forte if ((nb->len == 8) && 636*fcf3ce44SJohn Forte (strcmp(nconf->nc_protofmly, NC_INET6) == 0)) { 637*fcf3ce44SJohn Forte /* 638*fcf3ce44SJohn Forte * We have a mismatch in the netconfig retry 639*fcf3ce44SJohn Forte */ 640*fcf3ce44SJohn Forte free(nb); 641*fcf3ce44SJohn Forte goto retry; 642*fcf3ce44SJohn Forte } 643*fcf3ce44SJohn Forte #endif 644*fcf3ce44SJohn Forte } 645*fcf3ce44SJohn Forte } 646*fcf3ce44SJohn Forte 647*fcf3ce44SJohn Forte /* 648*fcf3ce44SJohn Forte * Got nconf and nb. Now dup the netconfig structure (nconf) 649*fcf3ce44SJohn Forte * and return it thru nconfp. 650*fcf3ce44SJohn Forte */ 651*fcf3ce44SJohn Forte *nconfp = getnetconfigent(nconf->nc_netid); 652*fcf3ce44SJohn Forte if (*nconfp == NULL) { 653*fcf3ce44SJohn Forte syslog(LOG_ERR, "no memory\n"); 654*fcf3ce44SJohn Forte free(nb); 655*fcf3ce44SJohn Forte nb = NULL; 656*fcf3ce44SJohn Forte } 657*fcf3ce44SJohn Forte done: 658*fcf3ce44SJohn Forte if (nc) 659*fcf3ce44SJohn Forte endnetpath(nc); 660*fcf3ce44SJohn Forte return (nb); 661*fcf3ce44SJohn Forte } 662*fcf3ce44SJohn Forte 663*fcf3ce44SJohn Forte 664*fcf3ce44SJohn Forte /* return values as for nsc_check_release() */ 665*fcf3ce44SJohn Forte int 666*fcf3ce44SJohn Forte rdc_check_release(char **reqd) 667*fcf3ce44SJohn Forte { 668*fcf3ce44SJohn Forte /* librdc.so must be built on the runtime OS release */ 669*fcf3ce44SJohn Forte return (nsc_check_release(BUILD_REV_STR, NULL, reqd)); 670*fcf3ce44SJohn Forte } 671