17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5004388ebScasper * Common Development and Distribution License (the "License").
6004388ebScasper * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
216935f61bSMarcel Telka
226935f61bSMarcel Telka /*
236935f61bSMarcel Telka * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
246935f61bSMarcel Telka */
256935f61bSMarcel Telka
267c478bd9Sstevel@tonic-gate /*
27004388ebScasper * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
287c478bd9Sstevel@tonic-gate * Use is subject to license terms.
297c478bd9Sstevel@tonic-gate */
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
327c478bd9Sstevel@tonic-gate /* All Rights Reserved */
337c478bd9Sstevel@tonic-gate
347c478bd9Sstevel@tonic-gate #include <ctype.h>
357c478bd9Sstevel@tonic-gate #include <stdio.h>
367c478bd9Sstevel@tonic-gate #include <tiuser.h>
377c478bd9Sstevel@tonic-gate #include <netdir.h>
387c478bd9Sstevel@tonic-gate #include <netconfig.h>
397c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
407c478bd9Sstevel@tonic-gate #include <sys/param.h>
417c478bd9Sstevel@tonic-gate #include <string.h>
427c478bd9Sstevel@tonic-gate #include <stdlib.h>
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate /*
457c478bd9Sstevel@tonic-gate * The generic name to address mappings for any transport that
467c478bd9Sstevel@tonic-gate * has strings for address (e.g., ISO Starlan).
477c478bd9Sstevel@tonic-gate *
487c478bd9Sstevel@tonic-gate * Address in ISO Starlan consist of arbitrary strings of
497c478bd9Sstevel@tonic-gate * characters. Because of this, the following routines
507c478bd9Sstevel@tonic-gate * create an "address" based on two strings, one gotten
517c478bd9Sstevel@tonic-gate * from a "host" file and one gotten from a "services" file.
527c478bd9Sstevel@tonic-gate * The two strings are catenated together (with a "." between
537c478bd9Sstevel@tonic-gate * them). The hosts file is /etc/net/starlan/hosts and
547c478bd9Sstevel@tonic-gate * contain lines of the form:
557c478bd9Sstevel@tonic-gate *
567c478bd9Sstevel@tonic-gate * arbitrary_string machname
577c478bd9Sstevel@tonic-gate *
587c478bd9Sstevel@tonic-gate * To make things simple, the "arbitrary string" should be the
597c478bd9Sstevel@tonic-gate * machine name.
607c478bd9Sstevel@tonic-gate *
617c478bd9Sstevel@tonic-gate * The services file is /etc/net/starlan/services and has lines
627c478bd9Sstevel@tonic-gate * of the form:
637c478bd9Sstevel@tonic-gate *
647c478bd9Sstevel@tonic-gate * service_name arbitrary_string
657c478bd9Sstevel@tonic-gate *
667c478bd9Sstevel@tonic-gate * Again, to make things easer, the "arbitrary name" should be the
677c478bd9Sstevel@tonic-gate * service name.
687c478bd9Sstevel@tonic-gate */
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate #define HOSTFILE "/etc/net/%s/hosts"
717c478bd9Sstevel@tonic-gate #define SERVICEFILE "/etc/net/%s/services"
727c478bd9Sstevel@tonic-gate #define FIELD1 1
737c478bd9Sstevel@tonic-gate #define FIELD2 2
746935f61bSMarcel Telka #define LOCALHOST "localhost"
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gate static int searchhost(struct netconfig *, char *, int, char *);
777c478bd9Sstevel@tonic-gate static int searchserv(struct netconfig *, char *, int, char *);
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate /*
807c478bd9Sstevel@tonic-gate * _netdir_getbyname() returns all of the addresses for
817c478bd9Sstevel@tonic-gate * a specified host and service.
827c478bd9Sstevel@tonic-gate */
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate struct nd_addrlist *
_netdir_getbyname(struct netconfig * netconfigp,struct nd_hostserv * nd_hostservp)857c478bd9Sstevel@tonic-gate _netdir_getbyname(struct netconfig *netconfigp,
867c478bd9Sstevel@tonic-gate struct nd_hostserv *nd_hostservp)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate char fulladdr[BUFSIZ]; /* holds the full address string */
897c478bd9Sstevel@tonic-gate struct nd_addrlist *retp; /* the return structure */
907c478bd9Sstevel@tonic-gate struct netbuf *netbufp; /* indexes through the addresses */
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate /*
937c478bd9Sstevel@tonic-gate * HOST_BROADCAST is not supported.
947c478bd9Sstevel@tonic-gate */
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate if (strcmp(nd_hostservp->h_host, HOST_BROADCAST) == 0) {
977c478bd9Sstevel@tonic-gate _nderror = ND_NOHOST;
987c478bd9Sstevel@tonic-gate return (NULL);
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate if (searchhost(netconfigp, nd_hostservp->h_host, FIELD2,
1027c478bd9Sstevel@tonic-gate fulladdr) == 0) {
1037c478bd9Sstevel@tonic-gate _nderror = ND_NOHOST;
1047c478bd9Sstevel@tonic-gate return (NULL);
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate /*
1087c478bd9Sstevel@tonic-gate * Now simply fill in the address by forming strings of the
1097c478bd9Sstevel@tonic-gate * form "string_from_hosts.string_from_services"
1107c478bd9Sstevel@tonic-gate */
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate if (nd_hostservp->h_serv &&
1137c478bd9Sstevel@tonic-gate (strcmp(nd_hostservp->h_serv, "rpcbind") == 0)) {
1147c478bd9Sstevel@tonic-gate (void) strcat(fulladdr, ".");
1157c478bd9Sstevel@tonic-gate (void) strcat(fulladdr, "rpc"); /* hard coded */
1167c478bd9Sstevel@tonic-gate } else {
1177c478bd9Sstevel@tonic-gate /*
1187c478bd9Sstevel@tonic-gate * Get the address from the services file
1197c478bd9Sstevel@tonic-gate */
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate if (nd_hostservp->h_serv && (nd_hostservp->h_serv[0] != '\0')) {
1227c478bd9Sstevel@tonic-gate (void) strcat(fulladdr, ".");
1237c478bd9Sstevel@tonic-gate if (searchserv(netconfigp, nd_hostservp->h_serv, FIELD1,
1247c478bd9Sstevel@tonic-gate fulladdr + strlen(fulladdr)) == 0) {
1257c478bd9Sstevel@tonic-gate _nderror = ND_NOSERV;
1267c478bd9Sstevel@tonic-gate return (NULL);
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gate if ((retp = malloc(sizeof (struct nd_addrlist))) == NULL) {
1327c478bd9Sstevel@tonic-gate _nderror = ND_NOMEM;
1337c478bd9Sstevel@tonic-gate return (NULL);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate /*
1377c478bd9Sstevel@tonic-gate * We do not worry about multiple addresses here. Loopbacks
1387c478bd9Sstevel@tonic-gate * have only one interface.
1397c478bd9Sstevel@tonic-gate */
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate retp->n_cnt = 1;
1427c478bd9Sstevel@tonic-gate if ((retp->n_addrs = malloc(sizeof (struct netbuf))) == NULL) {
1437c478bd9Sstevel@tonic-gate free(retp);
1447c478bd9Sstevel@tonic-gate _nderror = ND_NOMEM;
1457c478bd9Sstevel@tonic-gate return (NULL);
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate netbufp = retp->n_addrs;
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate /*
1517c478bd9Sstevel@tonic-gate * Don't include the terminating NULL character in the
1527c478bd9Sstevel@tonic-gate * length.
1537c478bd9Sstevel@tonic-gate */
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate netbufp->len = netbufp->maxlen = (int)strlen(fulladdr);
1567c478bd9Sstevel@tonic-gate if ((netbufp->buf = strdup(fulladdr)) == NULL) {
1577c478bd9Sstevel@tonic-gate free(netbufp);
1587c478bd9Sstevel@tonic-gate free(retp);
1597c478bd9Sstevel@tonic-gate _nderror = ND_NOMEM;
1607c478bd9Sstevel@tonic-gate return (NULL);
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate _nderror = ND_OK;
1637c478bd9Sstevel@tonic-gate return (retp);
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate /*
1677c478bd9Sstevel@tonic-gate * _netdir_getbyaddr() takes an address (hopefully obtained from
1687c478bd9Sstevel@tonic-gate * someone doing a _netdir_getbyname()) and returns all hosts with
1697c478bd9Sstevel@tonic-gate * that address.
1707c478bd9Sstevel@tonic-gate */
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate struct nd_hostservlist *
_netdir_getbyaddr(struct netconfig * netconfigp,struct netbuf * netbufp)1737c478bd9Sstevel@tonic-gate _netdir_getbyaddr(struct netconfig *netconfigp, struct netbuf *netbufp)
1747c478bd9Sstevel@tonic-gate {
1757c478bd9Sstevel@tonic-gate char fulladdr[BUFSIZ]; /* a copy of the address string */
1767c478bd9Sstevel@tonic-gate char servbuf[BUFSIZ]; /* a buffer for service string */
1777c478bd9Sstevel@tonic-gate char hostbuf[BUFSIZ]; /* points to list of host names */
1787c478bd9Sstevel@tonic-gate char *hostname; /* the "first" path of the string */
1797c478bd9Sstevel@tonic-gate char *servname; /* the "second" part of string */
1807c478bd9Sstevel@tonic-gate struct nd_hostservlist *retp; /* the return structure */
1817c478bd9Sstevel@tonic-gate char *serv; /* resultant service name obtained */
1827c478bd9Sstevel@tonic-gate int nhost; /* the number of hosts in hostpp */
1837c478bd9Sstevel@tonic-gate struct nd_hostserv *nd_hostservp; /* traverses the host structures */
1847c478bd9Sstevel@tonic-gate char *nexttok; /* next token to process */
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate /*
1877c478bd9Sstevel@tonic-gate * Separate the two parts of the address string.
1887c478bd9Sstevel@tonic-gate */
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gate (void) strlcpy(fulladdr, netbufp->buf, sizeof (fulladdr));
1917c478bd9Sstevel@tonic-gate hostname = strtok_r(fulladdr, ".", &nexttok);
1927c478bd9Sstevel@tonic-gate if (hostname == NULL) {
1937c478bd9Sstevel@tonic-gate _nderror = ND_NOHOST;
1947c478bd9Sstevel@tonic-gate return (NULL);
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate servname = strtok_r(NULL, " \n\t", &nexttok);
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate /*
1997c478bd9Sstevel@tonic-gate * Search for all the hosts associated with the
2007c478bd9Sstevel@tonic-gate * first part of the address string.
2017c478bd9Sstevel@tonic-gate */
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate nhost = searchhost(netconfigp, hostname, FIELD1, hostbuf);
2047c478bd9Sstevel@tonic-gate if (nhost == 0) {
2057c478bd9Sstevel@tonic-gate _nderror = ND_NOHOST;
2067c478bd9Sstevel@tonic-gate return (NULL);
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate /*
2107c478bd9Sstevel@tonic-gate * Search for the service associated with the second
2117c478bd9Sstevel@tonic-gate * path of the address string.
2127c478bd9Sstevel@tonic-gate */
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate if (servname == NULL) {
2157c478bd9Sstevel@tonic-gate _nderror = ND_NOSERV;
2167c478bd9Sstevel@tonic-gate return (NULL);
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate servbuf[0] = '\0';
2207c478bd9Sstevel@tonic-gate serv = servbuf;
2217c478bd9Sstevel@tonic-gate if (searchserv(netconfigp, servname, FIELD2, servbuf) == 0) {
2227c478bd9Sstevel@tonic-gate serv = _taddr2uaddr(netconfigp, netbufp);
2237c478bd9Sstevel@tonic-gate (void) strcpy(servbuf, serv);
2247c478bd9Sstevel@tonic-gate free(serv);
2257c478bd9Sstevel@tonic-gate serv = servbuf;
2267c478bd9Sstevel@tonic-gate while (*serv != '.')
2277c478bd9Sstevel@tonic-gate serv++;
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate /*
2317c478bd9Sstevel@tonic-gate * Allocate space to hold the return structure, set the number
2327c478bd9Sstevel@tonic-gate * of hosts, and allocate space to hold them.
2337c478bd9Sstevel@tonic-gate */
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate if ((retp = malloc(sizeof (struct nd_hostservlist))) == NULL) {
2367c478bd9Sstevel@tonic-gate _nderror = ND_NOMEM;
2377c478bd9Sstevel@tonic-gate return (NULL);
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate retp->h_cnt = nhost;
2417c478bd9Sstevel@tonic-gate retp->h_hostservs = calloc(nhost, sizeof (struct nd_hostserv));
2427c478bd9Sstevel@tonic-gate if (retp->h_hostservs == NULL) {
2437c478bd9Sstevel@tonic-gate free(retp);
2447c478bd9Sstevel@tonic-gate _nderror = ND_NOMEM;
2457c478bd9Sstevel@tonic-gate return (NULL);
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate /*
2497c478bd9Sstevel@tonic-gate * Loop through the host structues and fill them in with
2507c478bd9Sstevel@tonic-gate * each host name (and service name).
2517c478bd9Sstevel@tonic-gate */
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate nd_hostservp = retp->h_hostservs;
2547c478bd9Sstevel@tonic-gate hostname = strtok_r(hostbuf, ",", &nexttok);
2557c478bd9Sstevel@tonic-gate while (hostname && nhost--) {
2567c478bd9Sstevel@tonic-gate if (((nd_hostservp->h_host = strdup(hostname)) == NULL) ||
2577c478bd9Sstevel@tonic-gate ((nd_hostservp->h_serv = strdup(serv)) == NULL)) {
2587c478bd9Sstevel@tonic-gate netdir_free(retp, ND_HOSTSERVLIST);
2597c478bd9Sstevel@tonic-gate _nderror = ND_NOMEM;
2607c478bd9Sstevel@tonic-gate return (NULL);
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate nd_hostservp++;
2637c478bd9Sstevel@tonic-gate hostname = strtok_r(NULL, ",", &nexttok);
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate _nderror = ND_OK;
2677c478bd9Sstevel@tonic-gate return (retp);
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate
2707c478bd9Sstevel@tonic-gate /*
2717c478bd9Sstevel@tonic-gate * _taddr2uaddr() translates a address into a "universal" address.
2727c478bd9Sstevel@tonic-gate * Since the address is a string, simply return the string as the
2737c478bd9Sstevel@tonic-gate * universal address (but replace all non-printable characters with
2747c478bd9Sstevel@tonic-gate * the \ddd form, where ddd is three octal digits). The '\n' character
2757c478bd9Sstevel@tonic-gate * is also replace by \ddd and the '\' character is placed as two
2767c478bd9Sstevel@tonic-gate * '\' characters.
2777c478bd9Sstevel@tonic-gate */
2787c478bd9Sstevel@tonic-gate
2797c478bd9Sstevel@tonic-gate /* ARGSUSED */
2807c478bd9Sstevel@tonic-gate char *
_taddr2uaddr(struct netconfig * netconfigp,struct netbuf * netbufp)2817c478bd9Sstevel@tonic-gate _taddr2uaddr(struct netconfig *netconfigp, struct netbuf *netbufp)
2827c478bd9Sstevel@tonic-gate {
2837c478bd9Sstevel@tonic-gate char *retp; /* pointer the return string */
2847c478bd9Sstevel@tonic-gate char *to; /* traverses and populates the return string */
2857c478bd9Sstevel@tonic-gate char *from; /* traverses the string to be converted */
2867c478bd9Sstevel@tonic-gate int i; /* indexes through the given string */
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate /*
2897c478bd9Sstevel@tonic-gate * BUFSIZ is perhaps too big for this one and there is a better
2907c478bd9Sstevel@tonic-gate * way to optimize it, but for now we will just assume BUFSIZ
2917c478bd9Sstevel@tonic-gate */
2927c478bd9Sstevel@tonic-gate if ((retp = malloc(BUFSIZ)) == NULL) {
2937c478bd9Sstevel@tonic-gate _nderror = ND_NOMEM;
2947c478bd9Sstevel@tonic-gate return (NULL);
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate to = retp;
2977c478bd9Sstevel@tonic-gate from = netbufp->buf;
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate for (i = 0; i < netbufp->len; i++) {
3007c478bd9Sstevel@tonic-gate if (*from == '\\') {
3017c478bd9Sstevel@tonic-gate *to++ = '\\';
3027c478bd9Sstevel@tonic-gate *to++ = '\\';
3037c478bd9Sstevel@tonic-gate } else {
3047c478bd9Sstevel@tonic-gate if (*from == '\n' || !isprint((unsigned char)*from)) {
3057c478bd9Sstevel@tonic-gate (void) sprintf(to, "\\%.3o", *from & 0xff);
3067c478bd9Sstevel@tonic-gate to += 4;
3077c478bd9Sstevel@tonic-gate } else {
3087c478bd9Sstevel@tonic-gate *to++ = *from;
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate }
3117c478bd9Sstevel@tonic-gate from++;
3127c478bd9Sstevel@tonic-gate }
3137c478bd9Sstevel@tonic-gate *to = '\0';
3147c478bd9Sstevel@tonic-gate return (retp);
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate
3177c478bd9Sstevel@tonic-gate /*
3187c478bd9Sstevel@tonic-gate * _uaddr2taddr() translates a universal address back into a
3197c478bd9Sstevel@tonic-gate * netaddr structure. Since the universal address is a string,
3207c478bd9Sstevel@tonic-gate * put that into the TLI buffer (making sure to change all \ddd
3217c478bd9Sstevel@tonic-gate * characters back and strip off the trailing \0 character).
3227c478bd9Sstevel@tonic-gate */
3237c478bd9Sstevel@tonic-gate
3247c478bd9Sstevel@tonic-gate /* ARGSUSED */
3257c478bd9Sstevel@tonic-gate struct netbuf *
_uaddr2taddr(struct netconfig * netconfigp,char * uaddr)3267c478bd9Sstevel@tonic-gate _uaddr2taddr(struct netconfig *netconfigp, char *uaddr)
3277c478bd9Sstevel@tonic-gate {
3287c478bd9Sstevel@tonic-gate struct netbuf *retp; /* the return structure */
3297c478bd9Sstevel@tonic-gate char *holdp; /* holds the converted address */
3307c478bd9Sstevel@tonic-gate char *to; /* traverses and populates the new address */
3317c478bd9Sstevel@tonic-gate char *from; /* traverses the universal address */
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate holdp = malloc(strlen(uaddr) + 1);
3347c478bd9Sstevel@tonic-gate if (holdp == NULL) {
3357c478bd9Sstevel@tonic-gate _nderror = ND_NOMEM;
3367c478bd9Sstevel@tonic-gate return (NULL);
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate from = uaddr;
3397c478bd9Sstevel@tonic-gate to = holdp;
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate while (*from) {
3427c478bd9Sstevel@tonic-gate if (*from == '\\') {
3437c478bd9Sstevel@tonic-gate if (*(from+1) == '\\') {
3447c478bd9Sstevel@tonic-gate *to = '\\';
3457c478bd9Sstevel@tonic-gate from += 2;
3467c478bd9Sstevel@tonic-gate } else {
3477c478bd9Sstevel@tonic-gate *to = ((*(from+1) - '0') << 6) +
3486935f61bSMarcel Telka ((*(from+2) - '0') << 3) +
3496935f61bSMarcel Telka (*(from+3) - '0');
3507c478bd9Sstevel@tonic-gate from += 4;
3517c478bd9Sstevel@tonic-gate }
3527c478bd9Sstevel@tonic-gate } else {
3537c478bd9Sstevel@tonic-gate *to = *from++;
3547c478bd9Sstevel@tonic-gate }
3557c478bd9Sstevel@tonic-gate to++;
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate *to = '\0';
3587c478bd9Sstevel@tonic-gate
3597c478bd9Sstevel@tonic-gate if ((retp = malloc(sizeof (struct netbuf))) == NULL) {
3607c478bd9Sstevel@tonic-gate free(holdp);
3617c478bd9Sstevel@tonic-gate _nderror = ND_NOMEM;
3627c478bd9Sstevel@tonic-gate return (NULL);
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate retp->maxlen = retp->len = (int)(to - holdp);
3657c478bd9Sstevel@tonic-gate retp->buf = holdp;
3667c478bd9Sstevel@tonic-gate return (retp);
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate
3697c478bd9Sstevel@tonic-gate /*
3707c478bd9Sstevel@tonic-gate * _netdir_options() is a "catch-all" routine that does
3717c478bd9Sstevel@tonic-gate * transport specific things. The only thing that these
3727c478bd9Sstevel@tonic-gate * routines have to worry about is ND_MERGEADDR.
3737c478bd9Sstevel@tonic-gate */
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate /* ARGSUSED */
3767c478bd9Sstevel@tonic-gate int
_netdir_options(struct netconfig * netconfigp,int option,int fd,void * par)3777c478bd9Sstevel@tonic-gate _netdir_options(struct netconfig *netconfigp, int option, int fd, void *par)
3787c478bd9Sstevel@tonic-gate {
3797c478bd9Sstevel@tonic-gate struct nd_mergearg *argp; /* the argument for mergeaddr */
3807c478bd9Sstevel@tonic-gate
3817c478bd9Sstevel@tonic-gate switch (option) {
3827c478bd9Sstevel@tonic-gate case ND_MERGEADDR:
3837c478bd9Sstevel@tonic-gate /*
3847c478bd9Sstevel@tonic-gate * Translate the universal address into something that
3857c478bd9Sstevel@tonic-gate * makes sense to the caller. This is a no-op in
3867c478bd9Sstevel@tonic-gate * loopback's case, so just return the universal address.
3877c478bd9Sstevel@tonic-gate */
3887c478bd9Sstevel@tonic-gate argp = (struct nd_mergearg *)par;
3897c478bd9Sstevel@tonic-gate argp->m_uaddr = strdup(argp->s_uaddr);
390*9d4de077SMarcel Telka if (argp->m_uaddr == NULL) {
391*9d4de077SMarcel Telka _nderror = ND_NOMEM;
392*9d4de077SMarcel Telka return (-1);
393*9d4de077SMarcel Telka }
394*9d4de077SMarcel Telka return (0);
3957c478bd9Sstevel@tonic-gate default:
3967c478bd9Sstevel@tonic-gate _nderror = ND_NOCTRL;
3977c478bd9Sstevel@tonic-gate return (-1);
3987c478bd9Sstevel@tonic-gate }
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate
4017c478bd9Sstevel@tonic-gate /*
4027c478bd9Sstevel@tonic-gate * searchhost() looks for the specified token in the host file.
4037c478bd9Sstevel@tonic-gate * The "field" parameter signifies which field to compare the token
4047c478bd9Sstevel@tonic-gate * on, and returns all comma separated values associated with the token.
4057c478bd9Sstevel@tonic-gate */
4067c478bd9Sstevel@tonic-gate
4077c478bd9Sstevel@tonic-gate static int
searchhost(struct netconfig * netconfigp,char * token,int field,char * hostbuf)4087c478bd9Sstevel@tonic-gate searchhost(struct netconfig *netconfigp, char *token, int field, char *hostbuf)
4097c478bd9Sstevel@tonic-gate {
4107c478bd9Sstevel@tonic-gate char searchfile[MAXPATHLEN]; /* the name of file to be opened */
4117c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; /* holds each line of the file */
4127c478bd9Sstevel@tonic-gate char *fileaddr; /* the first token in each line */
4137c478bd9Sstevel@tonic-gate char *filehost; /* the second token in each line */
4147c478bd9Sstevel@tonic-gate char *cmpstr; /* the string to compare token to */
4157c478bd9Sstevel@tonic-gate char *retstr; /* the string to return if compare succeeds */
4167c478bd9Sstevel@tonic-gate char *nexttok; /* next token to process */
4177c478bd9Sstevel@tonic-gate FILE *fp; /* the opened searchfile */
4187c478bd9Sstevel@tonic-gate int nelements = 0; /* total number of elements found */
4196935f61bSMarcel Telka struct utsname utsname;
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate /*
4226935f61bSMarcel Telka * Unless /etc/netconfig has been altered, the only transport that
4236935f61bSMarcel Telka * will use straddr.so is loopback. In this case, we always
4246935f61bSMarcel Telka * return "localhost" if either our nodename, or "localhost", or
4256935f61bSMarcel Telka * some of special-case host names were passed, or we fail.
4267c478bd9Sstevel@tonic-gate */
4277c478bd9Sstevel@tonic-gate
4287c478bd9Sstevel@tonic-gate if ((strcmp(token, HOST_SELF_BIND) == 0) ||
4297c478bd9Sstevel@tonic-gate (strcmp(token, HOST_SELF_CONNECT) == 0) ||
4307c478bd9Sstevel@tonic-gate (strcmp(token, HOST_ANY) == 0) ||
4316935f61bSMarcel Telka (strcmp(token, LOCALHOST) == 0) ||
4326935f61bSMarcel Telka (uname(&utsname) >= 0 && strcmp(token, utsname.nodename) == 0)) {
4336935f61bSMarcel Telka (void) strcpy(hostbuf, LOCALHOST);
4347c478bd9Sstevel@tonic-gate return (1);
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate if (strcmp(netconfigp->nc_protofmly, NC_LOOPBACK) == 0)
4387c478bd9Sstevel@tonic-gate return (0);
4397c478bd9Sstevel@tonic-gate
4407c478bd9Sstevel@tonic-gate /*
4417c478bd9Sstevel@tonic-gate * We only get here if an administrator has modified
4427c478bd9Sstevel@tonic-gate * /etc/netconfig to use straddr.so for a transport other than
4437c478bd9Sstevel@tonic-gate * loopback (which is questionable but something we'll need to
4447c478bd9Sstevel@tonic-gate * EOL at a later point in time). In this case, we fallback to
4457c478bd9Sstevel@tonic-gate * searching for the associated key in the appropriate hosts
4467c478bd9Sstevel@tonic-gate * file (based on nc_netid).
4477c478bd9Sstevel@tonic-gate */
4487c478bd9Sstevel@tonic-gate
4497c478bd9Sstevel@tonic-gate (void) snprintf(searchfile, sizeof (searchfile), HOSTFILE,
4507c478bd9Sstevel@tonic-gate netconfigp->nc_netid);
4517c478bd9Sstevel@tonic-gate
452004388ebScasper fp = fopen(searchfile, "rF");
4537c478bd9Sstevel@tonic-gate if (fp == NULL)
4547c478bd9Sstevel@tonic-gate return (0);
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate /*
4577c478bd9Sstevel@tonic-gate * Loop through the file looking for the tokens and creating
4587c478bd9Sstevel@tonic-gate * the list of strings to be returned.
4597c478bd9Sstevel@tonic-gate */
4607c478bd9Sstevel@tonic-gate
4617c478bd9Sstevel@tonic-gate while (fgets(buf, BUFSIZ, fp) != NULL) {
4627c478bd9Sstevel@tonic-gate
4637c478bd9Sstevel@tonic-gate /*
4647c478bd9Sstevel@tonic-gate * Ignore comments and bad lines.
4657c478bd9Sstevel@tonic-gate */
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate fileaddr = strtok_r(buf, " \t\n", &nexttok);
4687c478bd9Sstevel@tonic-gate if (fileaddr == NULL || *fileaddr == '#')
4697c478bd9Sstevel@tonic-gate continue;
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate if ((filehost = strtok_r(NULL, " \t\n", &nexttok)) == NULL)
4727c478bd9Sstevel@tonic-gate continue;
4737c478bd9Sstevel@tonic-gate
4747c478bd9Sstevel@tonic-gate /*
4757c478bd9Sstevel@tonic-gate * determine which to compare the token to, then
4767c478bd9Sstevel@tonic-gate * compare it, and if they match, add the return
4777c478bd9Sstevel@tonic-gate * string to the list.
4787c478bd9Sstevel@tonic-gate */
4797c478bd9Sstevel@tonic-gate
4807c478bd9Sstevel@tonic-gate cmpstr = (field == FIELD1)? fileaddr : filehost;
4817c478bd9Sstevel@tonic-gate retstr = (field == FIELD1)? filehost : fileaddr;
4827c478bd9Sstevel@tonic-gate
4837c478bd9Sstevel@tonic-gate if (strcmp(token, cmpstr) == 0) {
4847c478bd9Sstevel@tonic-gate nelements++;
4857c478bd9Sstevel@tonic-gate if (field == FIELD2) {
4867c478bd9Sstevel@tonic-gate /*
4877c478bd9Sstevel@tonic-gate * called by _netdir_getbyname
4887c478bd9Sstevel@tonic-gate */
4897c478bd9Sstevel@tonic-gate
4907c478bd9Sstevel@tonic-gate (void) strcpy(hostbuf, retstr);
4917c478bd9Sstevel@tonic-gate break;
4927c478bd9Sstevel@tonic-gate }
4937c478bd9Sstevel@tonic-gate if (nelements > 1) {
4947c478bd9Sstevel@tonic-gate /*
4957c478bd9Sstevel@tonic-gate * Assuming that "," will never be a part
4967c478bd9Sstevel@tonic-gate * of any host name.
4977c478bd9Sstevel@tonic-gate */
4987c478bd9Sstevel@tonic-gate (void) strcat(hostbuf, ",");
4997c478bd9Sstevel@tonic-gate }
5007c478bd9Sstevel@tonic-gate (void) strcat(hostbuf, retstr);
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate
5047c478bd9Sstevel@tonic-gate (void) fclose(fp);
5057c478bd9Sstevel@tonic-gate return (nelements);
5067c478bd9Sstevel@tonic-gate }
5077c478bd9Sstevel@tonic-gate
5087c478bd9Sstevel@tonic-gate /*
5097c478bd9Sstevel@tonic-gate * searchserv() looks for the specified token in the service file.
5107c478bd9Sstevel@tonic-gate * The "field" parameter signifies which field to compare the token
5117c478bd9Sstevel@tonic-gate * on, and returns the string associated with the token in servname.
5127c478bd9Sstevel@tonic-gate */
5137c478bd9Sstevel@tonic-gate
5147c478bd9Sstevel@tonic-gate static int
searchserv(struct netconfig * netconfigp,char * token,int field,char * servname)5157c478bd9Sstevel@tonic-gate searchserv(struct netconfig *netconfigp, char *token, int field, char *servname)
5167c478bd9Sstevel@tonic-gate {
5177c478bd9Sstevel@tonic-gate char searchfile[MAXPATHLEN]; /* the name of file to be opened */
5187c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; /* buffer space for lines in file */
5197c478bd9Sstevel@tonic-gate char *fileservice; /* the first token in each line */
5207c478bd9Sstevel@tonic-gate char *fileport; /* the second token in each line */
5217c478bd9Sstevel@tonic-gate char *cmpstr; /* the string to compare the token to */
5227c478bd9Sstevel@tonic-gate char *retstr; /* temporarily hold token in line of file */
5237c478bd9Sstevel@tonic-gate char *nexttok; /* next token to process */
5247c478bd9Sstevel@tonic-gate FILE *fp; /* the opened searchfile */
5257c478bd9Sstevel@tonic-gate
5267c478bd9Sstevel@tonic-gate (void) snprintf(searchfile, sizeof (searchfile), SERVICEFILE,
5277c478bd9Sstevel@tonic-gate netconfigp->nc_netid);
5287c478bd9Sstevel@tonic-gate
529004388ebScasper fp = fopen(searchfile, "rF");
5307c478bd9Sstevel@tonic-gate if (fp == NULL)
5317c478bd9Sstevel@tonic-gate return (0);
5327c478bd9Sstevel@tonic-gate
5337c478bd9Sstevel@tonic-gate /*
5347c478bd9Sstevel@tonic-gate * Loop through the services file looking for the token.
5357c478bd9Sstevel@tonic-gate */
5367c478bd9Sstevel@tonic-gate
5377c478bd9Sstevel@tonic-gate while (fgets(buf, BUFSIZ, fp) != NULL) {
5387c478bd9Sstevel@tonic-gate /*
5397c478bd9Sstevel@tonic-gate * If comment or bad line, continue.
5407c478bd9Sstevel@tonic-gate */
5417c478bd9Sstevel@tonic-gate fileservice = strtok_r(buf, " \t\n", &nexttok);
5427c478bd9Sstevel@tonic-gate if (fileservice == NULL || *fileservice == '#')
5437c478bd9Sstevel@tonic-gate continue;
5447c478bd9Sstevel@tonic-gate
5457c478bd9Sstevel@tonic-gate if ((fileport = strtok_r(NULL, " \t\n", &nexttok)) == NULL)
5467c478bd9Sstevel@tonic-gate continue;
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate cmpstr = (field == FIELD1)? fileservice : fileport;
5497c478bd9Sstevel@tonic-gate retstr = (field == FIELD1)? fileport : fileservice;
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate if (strcmp(token, cmpstr) == 0) {
5527c478bd9Sstevel@tonic-gate (void) strcpy(servname, retstr);
5537c478bd9Sstevel@tonic-gate (void) fclose(fp);
5547c478bd9Sstevel@tonic-gate return (1);
5557c478bd9Sstevel@tonic-gate }
5567c478bd9Sstevel@tonic-gate }
5577c478bd9Sstevel@tonic-gate
5587c478bd9Sstevel@tonic-gate (void) fclose(fp);
5597c478bd9Sstevel@tonic-gate return (0);
5607c478bd9Sstevel@tonic-gate }
561