xref: /freebsd/lib/libc/net/getnetnamadr.c (revision 036ae3dd790971f07f3cf41e19e087973d0de986)
11363f04cSPaul Traina /*-
21363f04cSPaul Traina  * Copyright (c) 1994, Garrett Wollman
31363f04cSPaul Traina  *
41363f04cSPaul Traina  * Redistribution and use in source and binary forms, with or without
51363f04cSPaul Traina  * modification, are permitted provided that the following conditions
61363f04cSPaul Traina  * are met:
71363f04cSPaul Traina  * 1. Redistributions of source code must retain the above copyright
81363f04cSPaul Traina  *    notice, this list of conditions and the following disclaimer.
91363f04cSPaul Traina  * 2. Redistributions in binary form must reproduce the above copyright
101363f04cSPaul Traina  *    notice, this list of conditions and the following disclaimer in the
111363f04cSPaul Traina  *    documentation and/or other materials provided with the distribution.
121363f04cSPaul Traina  *
131363f04cSPaul Traina  * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
141363f04cSPaul Traina  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
151363f04cSPaul Traina  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
161363f04cSPaul Traina  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
171363f04cSPaul Traina  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
181363f04cSPaul Traina  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
191363f04cSPaul Traina  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
201363f04cSPaul Traina  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
211363f04cSPaul Traina  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
221363f04cSPaul Traina  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
231363f04cSPaul Traina  * SUCH DAMAGE.
241363f04cSPaul Traina  */
251363f04cSPaul Traina 
26333fc21eSDavid E. O'Brien #include <sys/cdefs.h>
27333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$");
281363f04cSPaul Traina 
29c5774e2dSJacques Vidrine #include "namespace.h"
30a2a77501SHajimu UMEMOTO #include "reentrant.h"
311363f04cSPaul Traina #include <sys/param.h>
321363f04cSPaul Traina #include <sys/socket.h>
331363f04cSPaul Traina #include <netinet/in.h>
341363f04cSPaul Traina #include <arpa/inet.h>
351363f04cSPaul Traina #include <netdb.h>
361363f04cSPaul Traina #include <stdio.h>
371363f04cSPaul Traina #include <ctype.h>
38a2a77501SHajimu UMEMOTO #include <stdlib.h>
391363f04cSPaul Traina #include <string.h>
40248aee62SJacques Vidrine #include <stdarg.h>
41248aee62SJacques Vidrine #include <nsswitch.h>
42c5774e2dSJacques Vidrine #include "un-namespace.h"
43bcb131aaSHajimu UMEMOTO #include "netdb_private.h"
441363f04cSPaul Traina 
45248aee62SJacques Vidrine extern int _ht_getnetbyname(void *, void *, va_list);
46248aee62SJacques Vidrine extern int _dns_getnetbyname(void *, void *, va_list);
47248aee62SJacques Vidrine extern int _nis_getnetbyname(void *, void *, va_list);
48248aee62SJacques Vidrine extern int _ht_getnetbyaddr(void *, void *, va_list);
49248aee62SJacques Vidrine extern int _dns_getnetbyaddr(void *, void *, va_list);
50248aee62SJacques Vidrine extern int _nis_getnetbyaddr(void *, void *, va_list);
511363f04cSPaul Traina 
52248aee62SJacques Vidrine /* Network lookup order if nsswitch.conf is broken or nonexistant */
53248aee62SJacques Vidrine static const ns_src default_src[] = {
54248aee62SJacques Vidrine 	{ NSSRC_FILES, NS_SUCCESS },
55248aee62SJacques Vidrine 	{ NSSRC_DNS, NS_SUCCESS },
56248aee62SJacques Vidrine 	{ 0 }
571363f04cSPaul Traina };
581363f04cSPaul Traina 
59a2a77501SHajimu UMEMOTO static struct netdata netdata;
60a2a77501SHajimu UMEMOTO static thread_key_t netdata_key;
61a2a77501SHajimu UMEMOTO static once_t netdata_init_once = ONCE_INITIALIZER;
62a2a77501SHajimu UMEMOTO static int netdata_thr_keycreated = 0;
63a2a77501SHajimu UMEMOTO 
64a2a77501SHajimu UMEMOTO static void
65a2a77501SHajimu UMEMOTO netdata_free(void *ptr)
661363f04cSPaul Traina {
67a2a77501SHajimu UMEMOTO 	struct netdata *nd = ptr;
68a2a77501SHajimu UMEMOTO 
69a2a77501SHajimu UMEMOTO 	if (nd == NULL)
70a2a77501SHajimu UMEMOTO 		return;
71a2a77501SHajimu UMEMOTO 	nd->data.stayopen = 0;
72a2a77501SHajimu UMEMOTO 	_endnethtent(&nd->data);
73a2a77501SHajimu UMEMOTO 	free(nd);
74a2a77501SHajimu UMEMOTO }
75a2a77501SHajimu UMEMOTO 
76a2a77501SHajimu UMEMOTO static void
77a2a77501SHajimu UMEMOTO netdata_keycreate(void)
78a2a77501SHajimu UMEMOTO {
79a2a77501SHajimu UMEMOTO 	netdata_thr_keycreated =
80a2a77501SHajimu UMEMOTO 	    (thr_keycreate(&netdata_key, netdata_free) == 0);
81a2a77501SHajimu UMEMOTO }
82a2a77501SHajimu UMEMOTO 
83a2a77501SHajimu UMEMOTO struct netdata *
84a2a77501SHajimu UMEMOTO __netdata_init(void)
85a2a77501SHajimu UMEMOTO {
86a2a77501SHajimu UMEMOTO 	struct netdata *nd;
87a2a77501SHajimu UMEMOTO 
88a2a77501SHajimu UMEMOTO 	if (thr_main() != 0)
89a2a77501SHajimu UMEMOTO 		return &netdata;
90a2a77501SHajimu UMEMOTO 	if (thr_once(&netdata_init_once, netdata_keycreate) != 0 ||
91a2a77501SHajimu UMEMOTO 	    !netdata_thr_keycreated)
92a2a77501SHajimu UMEMOTO 		return NULL;
93a2a77501SHajimu UMEMOTO 	if ((nd = thr_getspecific(netdata_key)) != NULL)
94a2a77501SHajimu UMEMOTO 		return nd;
95a2a77501SHajimu UMEMOTO 	if ((nd = calloc(1, sizeof(*nd))) == NULL)
96a2a77501SHajimu UMEMOTO 		return NULL;
97a2a77501SHajimu UMEMOTO 	if (thr_setspecific(netdata_key, nd) == 0)
98a2a77501SHajimu UMEMOTO 		return nd;
99a2a77501SHajimu UMEMOTO 	free(nd);
100a2a77501SHajimu UMEMOTO 	return NULL;
101a2a77501SHajimu UMEMOTO }
102a2a77501SHajimu UMEMOTO 
103a2a77501SHajimu UMEMOTO int
104a2a77501SHajimu UMEMOTO getnetbyname_r(const char *name, struct netent *ne, struct netent_data *ned)
105a2a77501SHajimu UMEMOTO {
106248aee62SJacques Vidrine 	int rval;
1071363f04cSPaul Traina 
1081363f04cSPaul Traina 
109248aee62SJacques Vidrine 	static const ns_dtab dtab[] = {
110248aee62SJacques Vidrine 		NS_FILES_CB(_ht_getnetbyname, NULL)
111248aee62SJacques Vidrine 		{ NSSRC_DNS, _dns_getnetbyname, NULL },
112248aee62SJacques Vidrine 		NS_NIS_CB(_nis_getnetbyname, NULL) /* force -DHESIOD */
113248aee62SJacques Vidrine 		{ 0 }
114248aee62SJacques Vidrine 	};
115248aee62SJacques Vidrine 
116a2a77501SHajimu UMEMOTO 	rval = _nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyname",
117a2a77501SHajimu UMEMOTO 	    default_src, name, ne, ned);
118248aee62SJacques Vidrine 
119a2a77501SHajimu UMEMOTO 	return (rval == NS_SUCCESS) ? 0 : -1;
1201363f04cSPaul Traina }
1211363f04cSPaul Traina 
122a2a77501SHajimu UMEMOTO int
123036ae3ddSHajimu UMEMOTO getnetbyaddr_r(uint32_t addr, int af, struct netent *ne,
124036ae3ddSHajimu UMEMOTO     struct netent_data *ned)
1251363f04cSPaul Traina {
126248aee62SJacques Vidrine 	int rval;
1271363f04cSPaul Traina 
128248aee62SJacques Vidrine 	static const ns_dtab dtab[] = {
129248aee62SJacques Vidrine 		NS_FILES_CB(_ht_getnetbyaddr, NULL)
130248aee62SJacques Vidrine 		{ NSSRC_DNS, _dns_getnetbyaddr, NULL },
131248aee62SJacques Vidrine 		NS_NIS_CB(_nis_getnetbyaddr, NULL) /* force -DHESIOD */
132248aee62SJacques Vidrine 		{ 0 }
133248aee62SJacques Vidrine 	};
1341363f04cSPaul Traina 
135a2a77501SHajimu UMEMOTO 	rval = _nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyaddr",
136a2a77501SHajimu UMEMOTO 	    default_src, addr, af, ne, ned);
137248aee62SJacques Vidrine 
138a2a77501SHajimu UMEMOTO 	return (rval == NS_SUCCESS) ? 0 : -1;
1391363f04cSPaul Traina }
1401363f04cSPaul Traina 
1411363f04cSPaul Traina void
142a2a77501SHajimu UMEMOTO setnetent_r(int stayopen, struct netent_data *ned)
1431363f04cSPaul Traina {
144a2a77501SHajimu UMEMOTO 	_setnethtent(stayopen, ned);
1451363f04cSPaul Traina 	_setnetdnsent(stayopen);
1461363f04cSPaul Traina }
1471363f04cSPaul Traina 
1481363f04cSPaul Traina void
149a2a77501SHajimu UMEMOTO endnetent_r(struct netent_data *ned)
1501363f04cSPaul Traina {
151a2a77501SHajimu UMEMOTO 	_endnethtent(ned);
1521363f04cSPaul Traina 	_endnetdnsent();
1531363f04cSPaul Traina }
154a2a77501SHajimu UMEMOTO 
155a2a77501SHajimu UMEMOTO struct netent *
156a2a77501SHajimu UMEMOTO getnetbyname(const char *name)
157a2a77501SHajimu UMEMOTO {
158a2a77501SHajimu UMEMOTO 	struct netdata *nd;
159a2a77501SHajimu UMEMOTO 
160a2a77501SHajimu UMEMOTO 	if ((nd = __netdata_init()) == NULL)
161a2a77501SHajimu UMEMOTO 		return NULL;
162a2a77501SHajimu UMEMOTO 	if (getnetbyname_r(name, &nd->net, &nd->data) != 0)
163a2a77501SHajimu UMEMOTO 		return NULL;
164a2a77501SHajimu UMEMOTO 	return &nd->net;
165a2a77501SHajimu UMEMOTO }
166a2a77501SHajimu UMEMOTO 
167a2a77501SHajimu UMEMOTO struct netent *
168036ae3ddSHajimu UMEMOTO #if __LONG_BIT == 64
169036ae3ddSHajimu UMEMOTO getnetbyaddr(u_long addr, int af)		/* ABI compatibility */
170036ae3ddSHajimu UMEMOTO #else
171036ae3ddSHajimu UMEMOTO getnetbyaddr(uint32_t addr, int af)
172036ae3ddSHajimu UMEMOTO #endif
173a2a77501SHajimu UMEMOTO {
174a2a77501SHajimu UMEMOTO 	struct netdata *nd;
175a2a77501SHajimu UMEMOTO 
176a2a77501SHajimu UMEMOTO 	if ((nd = __netdata_init()) == NULL)
177a2a77501SHajimu UMEMOTO 		return NULL;
178036ae3ddSHajimu UMEMOTO 	if (getnetbyaddr_r((uint32_t)addr, af, &nd->net, &nd->data) != 0)
179a2a77501SHajimu UMEMOTO 		return NULL;
180a2a77501SHajimu UMEMOTO 	return &nd->net;
181a2a77501SHajimu UMEMOTO }
182a2a77501SHajimu UMEMOTO 
183a2a77501SHajimu UMEMOTO void
184a2a77501SHajimu UMEMOTO setnetent(int stayopen)
185a2a77501SHajimu UMEMOTO {
186a2a77501SHajimu UMEMOTO 	struct netdata *nd;
187a2a77501SHajimu UMEMOTO 
188a2a77501SHajimu UMEMOTO 	if ((nd = __netdata_init()) == NULL)
189a2a77501SHajimu UMEMOTO 		return;
190a2a77501SHajimu UMEMOTO 	setnetent_r(stayopen, &nd->data);
191a2a77501SHajimu UMEMOTO }
192a2a77501SHajimu UMEMOTO 
193a2a77501SHajimu UMEMOTO void
194a2a77501SHajimu UMEMOTO endnetent(void)
195a2a77501SHajimu UMEMOTO {
196a2a77501SHajimu UMEMOTO 	struct netdata *nd;
197a2a77501SHajimu UMEMOTO 
198a2a77501SHajimu UMEMOTO 	if ((nd = __netdata_init()) == NULL)
199a2a77501SHajimu UMEMOTO 		return;
200a2a77501SHajimu UMEMOTO 	endnetent_r(&nd->data);
201a2a77501SHajimu UMEMOTO }
202