getnetbynis.c revision 156960
1/*-
2 * Copyright (c) 1994, Garrett Wollman
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26#include <sys/cdefs.h>
27__FBSDID("$FreeBSD: head/lib/libc/net/getnetbynis.c 156960 2006-03-21 16:11:11Z ume $");
28
29#include <sys/param.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/inet.h>
33#include <netdb.h>
34#include <resolv.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <ctype.h>
38#include <errno.h>
39#include <string.h>
40#include <stdarg.h>
41#include <nsswitch.h>
42#include <arpa/nameser.h>
43#ifdef YP
44#include <rpc/rpc.h>
45#include <rpcsvc/yp_prot.h>
46#include <rpcsvc/ypclnt.h>
47#endif
48#include "netdb_private.h"
49
50#ifdef YP
51static int
52_getnetbynis(const char *name, char *map, int af, struct netent *ne,
53    struct netent_data *ned)
54{
55	char *p, *bp, *ep;
56	char *cp, **q;
57	char *result;
58	int resultlen, len;
59	char ypbuf[YPMAXRECORD + 2];
60
61	switch(af) {
62	case AF_INET:
63		break;
64	default:
65	case AF_INET6:
66		errno = EAFNOSUPPORT;
67		return -1;
68	}
69
70	if (ned->yp_domain == (char *)NULL)
71		if (yp_get_default_domain (&ned->yp_domain))
72			return -1;
73
74	if (yp_match(ned->yp_domain, map, name, strlen(name), &result,
75	    &resultlen))
76		return -1;
77
78	bcopy((char *)result, (char *)&ypbuf, resultlen);
79	ypbuf[resultlen] = '\0';
80	free(result);
81	result = (char *)&ypbuf;
82
83	if ((cp = index(result, '\n')))
84		*cp = '\0';
85
86	cp = strpbrk(result, " \t");
87	*cp++ = '\0';
88	bp = ned->netbuf;
89	ep = ned->netbuf + sizeof ned->netbuf;
90	len = strlen(result) + 1;
91	if (ep - bp < len) {
92		RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
93		return -1;
94	}
95	strlcpy(bp, result, ep - bp);
96	ne->n_name = bp;
97	bp += len;
98
99	while (*cp == ' ' || *cp == '\t')
100		cp++;
101
102	ne->n_net = inet_network(cp);
103	ne->n_addrtype = AF_INET;
104
105	q = ne->n_aliases = ned->net_aliases;
106	cp = strpbrk(cp, " \t");
107	if (cp != NULL)
108		*cp++ = '\0';
109	while (cp && *cp) {
110		if (*cp == ' ' || *cp == '\t') {
111			cp++;
112			continue;
113		}
114		if (q > &ned->net_aliases[_MAXALIASES - 1])
115			break;
116		p = strpbrk(cp, " \t");
117		if (p != NULL)
118			*p++ = '\0';
119		len = strlen(cp) + 1;
120		if (ep - bp < len)
121			break;
122		strlcpy(bp, cp, ep - bp);
123		*q++ = bp;
124		bp += len;
125		cp = p;
126	}
127	*q = NULL;
128	return 0;
129}
130#endif /* YP */
131
132int
133_nis_getnetbyname(void *rval, void *cb_data, va_list ap)
134{
135#ifdef YP
136	const char *name;
137	struct netent *ne;
138	struct netent_data *ned;
139	int error;
140
141	name = va_arg(ap, const char *);
142	ne = va_arg(ap, struct netent *);
143	ned = va_arg(ap, struct netent_data *);
144
145	error = _getnetbynis(name, "networks.byname", AF_INET, ne, ned);
146	return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
147#else
148	return NS_UNAVAIL;
149#endif
150
151}
152
153int
154_nis_getnetbyaddr(void *rval, void *cb_data, va_list ap)
155{
156#ifdef YP
157	uint32_t addr;
158	int af;
159	struct netent *ne;
160	struct netent_data *ned;
161	char *str, *cp;
162	uint32_t net2;
163	int nn;
164	unsigned int netbr[4];
165	char buf[MAXDNAME];
166	int error;
167
168	addr = va_arg(ap, uint32_t);
169	af = va_arg(ap, int);
170	ne = va_arg(ap, struct netent *);
171	ned = va_arg(ap, struct netent_data *);
172
173	if (af != AF_INET) {
174		errno = EAFNOSUPPORT;
175		return NS_UNAVAIL;
176	}
177
178        for (nn = 4, net2 = addr; net2; net2 >>= 8) {
179                netbr[--nn] = net2 & 0xff;
180	}
181
182	switch (nn) {
183	case 3:		/* Class A */
184		sprintf(buf, "%u", netbr[3]);
185		break;
186        case 2:		/* Class B */
187		sprintf(buf, "%u.%u", netbr[2], netbr[3]);
188		break;
189        case 1:		/* Class C */
190		sprintf(buf, "%u.%u.%u", netbr[1], netbr[2], netbr[3]);
191                break;
192        case 0:		/* Class D - E */
193		sprintf(buf, "%u.%u.%u.%u", netbr[0], netbr[1],
194			netbr[2], netbr[3]);
195		break;
196	}
197
198	str = (char *)&buf;
199	cp = str + (strlen(str) - 2);
200
201	while(!strcmp(cp, ".0")) {
202		*cp = '\0';
203		cp = str + (strlen(str) - 2);
204	}
205
206	error = _getnetbynis(str, "networks.byaddr", af, ne, ned);
207	return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
208#else
209	return NS_UNAVAIL;
210#endif /* YP */
211}
212