2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A/*
2N/A * nis/getnetent.c -- "nis" backend for nsswitch "networks" database
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A#include "nis_common.h"
2N/A#include <synch.h>
2N/A#include <netdb.h>
2N/A#include <sys/socket.h>
2N/A#include <netinet/in.h>
2N/A#include <arpa/inet.h>
2N/A#include <string.h>
2N/A
2N/Astatic int nettoa(int anet, char *buf, int buflen, char **pnull);
2N/A
2N/Astatic nss_status_t
2N/Agetbyname(be, a)
2N/A nis_backend_ptr_t be;
2N/A void *a;
2N/A{
2N/A nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
2N/A
2N/A return (_nss_nis_lookup(be, argp, 1, "networks.byname",
2N/A argp->key.name, 0));
2N/A}
2N/A
2N/Astatic nss_status_t
2N/Agetbyaddr(be, a)
2N/A nis_backend_ptr_t be;
2N/A void *a;
2N/A{
2N/A nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
2N/A char addrstr[16];
2N/A char *pnull;
2N/A nss_status_t rc;
2N/A
2N/A if (nettoa((int)argp->key.netaddr.net, addrstr, 16, &pnull) != 0)
2N/A return (NSS_UNAVAIL); /* it's really ENOMEM */
2N/A rc = _nss_nis_lookup(be, argp, 1, "networks.byaddr", addrstr, 0);
2N/A
2N/A /*
2N/A * if not found, try again with the untruncated address string
2N/A * that has the trailing zero(s)
2N/A */
2N/A if (rc == NSS_NOTFOUND && pnull != NULL) {
2N/A *pnull = '.';
2N/A rc = _nss_nis_lookup(be, argp, 1, "networks.byaddr",
2N/A addrstr, 0);
2N/A }
2N/A return (rc);
2N/A}
2N/A
2N/Astatic nis_backend_op_t net_ops[] = {
2N/A _nss_nis_destr,
2N/A _nss_nis_endent,
2N/A _nss_nis_setent,
2N/A _nss_nis_getent_netdb,
2N/A getbyname,
2N/A getbyaddr
2N/A};
2N/A
2N/A/*ARGSUSED*/
2N/Anss_backend_t *
2N/A_nss_nis_networks_constr(dummy1, dummy2, dummy3)
2N/A const char *dummy1, *dummy2, *dummy3;
2N/A{
2N/A return (_nss_nis_constr(net_ops,
2N/A sizeof (net_ops) / sizeof (net_ops[0]),
2N/A "networks.byaddr"));
2N/A}
2N/A
2N/A/*
2N/A * Takes an unsigned integer in host order, and returns a printable
2N/A * string for it as a network number. To allow for the possibility of
2N/A * naming subnets, only trailing dot-zeros are truncated. The location
2N/A * where the string is truncated (or set to '\0') is returned in *pnull.
2N/A */
2N/Astatic int
2N/Anettoa(int anet, char *buf, int buflen, char **pnull)
2N/A{
2N/A char *p;
2N/A struct in_addr in;
2N/A int addr;
2N/A
2N/A *pnull = NULL;
2N/A
2N/A if (buf == 0)
2N/A return (1);
2N/A in = inet_makeaddr(anet, INADDR_ANY);
2N/A addr = in.s_addr;
2N/A (void) strncpy(buf, inet_ntoa(in), buflen);
2N/A if ((IN_CLASSA_HOST & htonl(addr)) == 0) {
2N/A p = strchr(buf, '.');
2N/A if (p == NULL)
2N/A return (1);
2N/A *p = 0;
2N/A *pnull = p;
2N/A } else if ((IN_CLASSB_HOST & htonl(addr)) == 0) {
2N/A p = strchr(buf, '.');
2N/A if (p == NULL)
2N/A return (1);
2N/A p = strchr(p+1, '.');
2N/A if (p == NULL)
2N/A return (1);
2N/A *p = 0;
2N/A *pnull = p;
2N/A } else if ((IN_CLASSC_HOST & htonl(addr)) == 0) {
2N/A p = strrchr(buf, '.');
2N/A if (p == NULL)
2N/A return (1);
2N/A *p = 0;
2N/A *pnull = p;
2N/A }
2N/A return (0);
2N/A}