straddr.c revision 6935f61b0d202f1b87f0234824e4a6ab88c492ac
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * CDDL HEADER START
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * The contents of this file are subject to the terms of the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Common Development and Distribution License (the "License").
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You may not use this file except in compliance with the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * See the License for the specific language governing permissions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and limitations under the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * When distributing Covered Code, include this CDDL HEADER in each
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If applicable, add the following below this CDDL HEADER, with the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fields enclosed by brackets "[]" replaced with your own identifying
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * information: Portions Copyright [yyyy] [name of copyright owner]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * CDDL HEADER END
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Use is subject to license terms.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz/* All Rights Reserved */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The generic name to address mappings for any transport that
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * has strings for address (e.g., ISO Starlan).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Address in ISO Starlan consist of arbitrary strings of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * characters. Because of this, the following routines
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * create an "address" based on two strings, one gotten
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * from a "host" file and one gotten from a "services" file.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * The two strings are catenated together (with a "." between
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * them). The hosts file is /etc/net/starlan/hosts and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * contain lines of the form:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * arbitrary_string machname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * To make things simple, the "arbitrary string" should be the
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * machine name.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The services file is /etc/net/starlan/services and has lines
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * of the form:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * service_name arbitrary_string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Again, to make things easer, the "arbitrary name" should be the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * service name.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int searchhost(struct netconfig *, char *, int, char *);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int searchserv(struct netconfig *, char *, int, char *);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * _netdir_getbyname() returns all of the addresses for
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * a specified host and service.
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner char fulladdr[BUFSIZ]; /* holds the full address string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct netbuf *netbufp; /* indexes through the addresses */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * HOST_BROADCAST is not supported.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strcmp(nd_hostservp->h_host, HOST_BROADCAST) == 0) {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (searchhost(netconfigp, nd_hostservp->h_host, FIELD2,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Now simply fill in the address by forming strings of the
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * form "string_from_hosts.string_from_services"
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * Get the address from the services file
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (nd_hostservp->h_serv && (nd_hostservp->h_serv[0] != '\0')) {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (searchserv(netconfigp, nd_hostservp->h_serv, FIELD1,
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((retp = malloc(sizeof (struct nd_addrlist))) == NULL) {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * We do not worry about multiple addresses here. Loopbacks
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * have only one interface.
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((retp->n_addrs = malloc(sizeof (struct netbuf))) == NULL) {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Don't include the terminating NULL character in the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin netbufp->len = netbufp->maxlen = (int)strlen(fulladdr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * _netdir_getbyaddr() takes an address (hopefully obtained from
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * someone doing a _netdir_getbyname()) and returns all hosts with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * that address.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz_netdir_getbyaddr(struct netconfig *netconfigp, struct netbuf *netbufp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char fulladdr[BUFSIZ]; /* a copy of the address string */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char servbuf[BUFSIZ]; /* a buffer for service string */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char hostbuf[BUFSIZ]; /* points to list of host names */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char *hostname; /* the "first" path of the string */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char *servname; /* the "second" part of string */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct nd_hostservlist *retp; /* the return structure */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char *serv; /* resultant service name obtained */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct nd_hostserv *nd_hostservp; /* traverses the host structures */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * Separate the two parts of the address string.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void) strlcpy(fulladdr, netbufp->buf, sizeof (fulladdr));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Search for all the hosts associated with the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * first part of the address string.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nhost = searchhost(netconfigp, hostname, FIELD1, hostbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (nhost == 0) {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Search for the service associated with the second
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * path of the address string.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (searchserv(netconfigp, servname, FIELD2, servbuf) == 0) {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Allocate space to hold the return structure, set the number
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * of hosts, and allocate space to hold them.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((retp = malloc(sizeof (struct nd_hostservlist))) == NULL) {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin retp->h_hostservs = calloc(nhost, sizeof (struct nd_hostserv));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Loop through the host structues and fill them in with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * each host name (and service name).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (((nd_hostservp->h_host = strdup(hostname)) == NULL) ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * _taddr2uaddr() translates a address into a "universal" address.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Since the address is a string, simply return the string as the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * universal address (but replace all non-printable characters with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the \ddd form, where ddd is three octal digits). The '\n' character
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * is also replace by \ddd and the '\' character is placed as two
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * '\' characters.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* ARGSUSED */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_taddr2uaddr(struct netconfig *netconfigp, struct netbuf *netbufp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *to; /* traverses and populates the return string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i; /* indexes through the given string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * BUFSIZ is perhaps too big for this one and there is a better
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * way to optimize it, but for now we will just assume BUFSIZ
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * _uaddr2taddr() translates a universal address back into a
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * netaddr structure. Since the universal address is a string,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * put that into the TLI buffer (making sure to change all \ddd
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * characters back and strip off the trailing \0 character).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* ARGSUSED */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *to; /* traverses and populates the new address */
while (*from) {
to++;
return (NULL);
return (retp);
switch (option) {
case ND_MERGEADDR:
* will use straddr.so is loopback. In this case, we always
nelements++;
return (nelements);