13070Spst/*-
23070Spst * Copyright (c) 1994, Garrett Wollman
33070Spst *
43070Spst * Redistribution and use in source and binary forms, with or without
53070Spst * modification, are permitted provided that the following conditions
63070Spst * are met:
73070Spst * 1. Redistributions of source code must retain the above copyright
83070Spst *    notice, this list of conditions and the following disclaimer.
93070Spst * 2. Redistributions in binary form must reproduce the above copyright
103070Spst *    notice, this list of conditions and the following disclaimer in the
113070Spst *    documentation and/or other materials provided with the distribution.
123070Spst *
133070Spst * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
143070Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
153070Spst * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
163070Spst * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
173070Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
183070Spst * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
193070Spst * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
203070Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
213070Spst * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
223070Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
233070Spst * SUCH DAMAGE.
243070Spst */
253070Spst
2692986Sobrien#include <sys/cdefs.h>
2792986Sobrien__FBSDID("$FreeBSD$");
283070Spst
293070Spst#include <sys/param.h>
303070Spst#include <sys/socket.h>
313070Spst#include <netinet/in.h>
323070Spst#include <arpa/inet.h>
333070Spst#include <netdb.h>
34156960Sume#include <resolv.h>
353070Spst#include <stdio.h>
3611661Sphk#include <stdlib.h>
373070Spst#include <ctype.h>
383070Spst#include <errno.h>
393070Spst#include <string.h>
4065532Snectar#include <stdarg.h>
4165532Snectar#include <nsswitch.h>
4214775Swpaul#include <arpa/nameser.h>
4314775Swpaul#ifdef YP
4414775Swpaul#include <rpc/rpc.h>
4514775Swpaul#include <rpcsvc/yp_prot.h>
4614775Swpaul#include <rpcsvc/ypclnt.h>
4714775Swpaul#endif
48145626Sume#include "netdb_private.h"
493070Spst
503070Spst#ifdef YP
51145626Sumestatic int
52145626Sume_getnetbynis(const char *name, char *map, int af, struct netent *ne,
53145626Sume    struct netent_data *ned)
543070Spst{
55145626Sume	char *p, *bp, *ep;
5692889Sobrien	char *cp, **q;
57145626Sume	char *result;
58145626Sume	int resultlen, len;
59145626Sume	char ypbuf[YPMAXRECORD + 2];
603070Spst
6117903Speter	switch(af) {
6217903Speter	case AF_INET:
6317903Speter		break;
6417903Speter	default:
6517903Speter	case AF_INET6:
6617903Speter		errno = EAFNOSUPPORT;
67157779Sume		return (-1);
6817903Speter	}
6917903Speter
70145626Sume	if (ned->yp_domain == (char *)NULL)
71145626Sume		if (yp_get_default_domain (&ned->yp_domain))
72157779Sume			return (-1);
733070Spst
74145626Sume	if (yp_match(ned->yp_domain, map, name, strlen(name), &result,
75145626Sume	    &resultlen))
76157779Sume		return (-1);
773070Spst
7814775Swpaul	bcopy((char *)result, (char *)&ypbuf, resultlen);
7920953Swpaul	ypbuf[resultlen] = '\0';
8014775Swpaul	free(result);
8114775Swpaul	result = (char *)&ypbuf;
8214775Swpaul
833070Spst	if ((cp = index(result, '\n')))
843070Spst		*cp = '\0';
853070Spst
863070Spst	cp = strpbrk(result, " \t");
873070Spst	*cp++ = '\0';
88145626Sume	bp = ned->netbuf;
89145626Sume	ep = ned->netbuf + sizeof ned->netbuf;
90145626Sume	len = strlen(result) + 1;
91145626Sume	if (ep - bp < len) {
92156960Sume		RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
93157779Sume		return (-1);
94145626Sume	}
95145626Sume	strlcpy(bp, result, ep - bp);
96145626Sume	ne->n_name = bp;
97145626Sume	bp += len;
983108Swollman
993070Spst	while (*cp == ' ' || *cp == '\t')
1003070Spst		cp++;
1013108Swollman
102145626Sume	ne->n_net = inet_network(cp);
103145626Sume	ne->n_addrtype = AF_INET;
1043108Swollman
105145626Sume	q = ne->n_aliases = ned->net_aliases;
1063070Spst	cp = strpbrk(cp, " \t");
1073070Spst	if (cp != NULL)
1083070Spst		*cp++ = '\0';
1093070Spst	while (cp && *cp) {
1103070Spst		if (*cp == ' ' || *cp == '\t') {
1113070Spst			cp++;
1123070Spst			continue;
1133070Spst		}
114145626Sume		if (q > &ned->net_aliases[_MAXALIASES - 1])
115145626Sume			break;
116145626Sume		p = strpbrk(cp, " \t");
117145626Sume		if (p != NULL)
118145626Sume			*p++ = '\0';
119145626Sume		len = strlen(cp) + 1;
120145626Sume		if (ep - bp < len)
121145626Sume			break;
122145626Sume		strlcpy(bp, cp, ep - bp);
123145626Sume		*q++ = bp;
124145626Sume		bp += len;
125145626Sume		cp = p;
1263070Spst	}
1273070Spst	*q = NULL;
128157779Sume	return (0);
12965532Snectar}
13065532Snectar#endif /* YP */
13165532Snectar
13265532Snectarint
13365532Snectar_nis_getnetbyname(void *rval, void *cb_data, va_list ap)
13465532Snectar{
13565532Snectar#ifdef YP
13665532Snectar	const char *name;
137157779Sume	char *buffer;
138157779Sume	size_t buflen;
139157779Sume	int *errnop, *h_errnop;
140157779Sume	struct netent *nptr, ne;
141145626Sume	struct netent_data *ned;
142157779Sume	res_state statp;
14365532Snectar
14465532Snectar	name = va_arg(ap, const char *);
145157779Sume	nptr = va_arg(ap, struct netent *);
146157779Sume	buffer = va_arg(ap, char *);
147157779Sume	buflen = va_arg(ap, size_t);
148157779Sume	errnop = va_arg(ap, int *);
149157779Sume	h_errnop = va_arg(ap, int *);
150145626Sume
151157779Sume	statp = __res_state();
152157779Sume	if ((ned = __netent_data_init()) == NULL) {
153157779Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
154157779Sume		*h_errnop = statp->res_h_errno;
155157779Sume		return (NS_UNAVAIL);
156157779Sume	}
157157779Sume
158157779Sume	if (_getnetbynis(name, "networks.byname", AF_INET, &ne, ned) != 0) {
159157779Sume		*h_errnop = statp->res_h_errno;
160157779Sume		return (NS_NOTFOUND);
161157779Sume	}
162157779Sume	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
163211276Sume		*errnop = errno;
164211276Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
165157779Sume		*h_errnop = statp->res_h_errno;
166211276Sume		return (NS_RETURN);
167157779Sume	}
168157779Sume	*((struct netent **)rval) = nptr;
169157779Sume	return (NS_SUCCESS);
1703070Spst#else
171157779Sume	return (NS_UNAVAIL);
1723070Spst#endif
17365532Snectar
1743070Spst}
1753070Spst
176146244Sumeint
17765532Snectar_nis_getnetbyaddr(void *rval, void *cb_data, va_list ap)
1783070Spst{
17965532Snectar#ifdef YP
180146244Sume	uint32_t addr;
18117903Speter	int af;
182157779Sume	char *buffer;
183157779Sume	size_t buflen;
184157779Sume	int *errnop, *h_errnop;
185157779Sume	struct netent *nptr, ne;
186145626Sume	struct netent_data *ned;
1873108Swollman	char *str, *cp;
188146244Sume	uint32_t net2;
18914775Swpaul	int nn;
19014775Swpaul	unsigned int netbr[4];
19114775Swpaul	char buf[MAXDNAME];
192157779Sume	res_state statp;
1933070Spst
194146244Sume	addr = va_arg(ap, uint32_t);
19565532Snectar	af = va_arg(ap, int);
196157779Sume	nptr = va_arg(ap, struct netent *);
197157779Sume	buffer = va_arg(ap, char *);
198157779Sume	buflen = va_arg(ap, size_t);
199157779Sume	errnop = va_arg(ap, int *);
200157779Sume	h_errnop = va_arg(ap, int *);
20165532Snectar
202157779Sume	statp = __res_state();
203157779Sume	if ((ned = __netent_data_init()) == NULL) {
204157779Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
205157779Sume		*h_errnop = statp->res_h_errno;
206157779Sume		return (NS_UNAVAIL);
207157779Sume	}
208157779Sume
20917903Speter	if (af != AF_INET) {
210157779Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
211157779Sume		*h_errnop = statp->res_h_errno;
21217903Speter		errno = EAFNOSUPPORT;
213157779Sume		return (NS_UNAVAIL);
21417903Speter	}
2153070Spst
21614775Swpaul        for (nn = 4, net2 = addr; net2; net2 >>= 8) {
21714775Swpaul                netbr[--nn] = net2 & 0xff;
21814775Swpaul	}
21914775Swpaul
22014775Swpaul	switch (nn) {
22114775Swpaul	case 3:		/* Class A */
22214775Swpaul		sprintf(buf, "%u", netbr[3]);
22314775Swpaul		break;
22414775Swpaul        case 2:		/* Class B */
22514775Swpaul		sprintf(buf, "%u.%u", netbr[2], netbr[3]);
22614775Swpaul		break;
22714775Swpaul        case 1:		/* Class C */
22814775Swpaul		sprintf(buf, "%u.%u.%u", netbr[1], netbr[2], netbr[3]);
22914775Swpaul                break;
23014775Swpaul        case 0:		/* Class D - E */
23114775Swpaul		sprintf(buf, "%u.%u.%u.%u", netbr[0], netbr[1],
23214775Swpaul			netbr[2], netbr[3]);
23314775Swpaul		break;
23414775Swpaul	}
23514775Swpaul
23614775Swpaul	str = (char *)&buf;
23714775Swpaul	cp = str + (strlen(str) - 2);
23814775Swpaul
2393108Swollman	while(!strcmp(cp, ".0")) {
2403108Swollman		*cp = '\0';
24114775Swpaul		cp = str + (strlen(str) - 2);
2423108Swollman	}
2438870Srgrimes
244157779Sume	if (_getnetbynis(str, "networks.byaddr", af, &ne, ned) != 0) {
245157779Sume		*h_errnop = statp->res_h_errno;
246157779Sume		return (NS_NOTFOUND);
247157779Sume	}
248157779Sume	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
249211276Sume		*errnop = errno;
250211276Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
251157779Sume		*h_errnop = statp->res_h_errno;
252211276Sume		return (NS_RETURN);
253157779Sume	}
254157779Sume	*((struct netent **)rval) = nptr;
255157779Sume	return (NS_SUCCESS);
25665532Snectar#else
257157779Sume	return (NS_UNAVAIL);
25865532Snectar#endif /* YP */
2593070Spst}
260