2 * Copyright (c) 1994, Garrett Wollman
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
25 * $FreeBSD: src/lib/libc/net/getnetnamadr.c,v 1.23 2006/04/28 12:03:35 ume Exp $
26 * $DragonFly: src/lib/libc/net/getnetnamadr.c,v 1.4 2005/11/13 02:04:47 swildner Exp $
29 #include "namespace.h"
30 #include "reentrant.h"
31 #include <sys/param.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
43 #include "un-namespace.h"
44 #include "netdb_private.h"
49 extern int _ht_getnetbyname(void *, void *, va_list);
50 extern int _dns_getnetbyname(void *, void *, va_list);
51 extern int _nis_getnetbyname(void *, void *, va_list);
52 extern int _ht_getnetbyaddr(void *, void *, va_list);
53 extern int _dns_getnetbyaddr(void *, void *, va_list);
54 extern int _nis_getnetbyaddr(void *, void *, va_list);
56 /* Network lookup order if nsswitch.conf is broken or nonexistant */
57 static const ns_src default_src
[] = {
58 { NSSRC_FILES
, NS_SUCCESS
},
59 { NSSRC_DNS
, NS_SUCCESS
},
63 NETDB_THREAD_ALLOC(netent_data
)
64 NETDB_THREAD_ALLOC(netdata
)
68 net_id_func(char *buffer
, size_t *buffer_size
, va_list ap
, void *cache_mdata
)
74 size_t desired_size
, size
;
75 enum nss_lookup_type lookup_type
;
78 lookup_type
= (enum nss_lookup_type
)cache_mdata
;
79 switch (lookup_type
) {
81 name
= va_arg(ap
, char *);
84 desired_size
= sizeof(enum nss_lookup_type
) + size
+ 1;
85 if (desired_size
> *buffer_size
) {
90 memcpy(buffer
, &lookup_type
, sizeof(enum nss_lookup_type
));
91 memcpy(buffer
+ sizeof(enum nss_lookup_type
), name
, size
+ 1);
96 net
= va_arg(ap
, uint32_t);
97 type
= va_arg(ap
, int);
99 desired_size
= sizeof(enum nss_lookup_type
) +
100 sizeof(uint32_t) + sizeof(int);
101 if (desired_size
> *buffer_size
) {
106 memcpy(buffer
, &lookup_type
, sizeof(enum nss_lookup_type
));
107 memcpy(buffer
+ sizeof(enum nss_lookup_type
), &net
,
109 memcpy(buffer
+ sizeof(enum nss_lookup_type
) + sizeof(uint32_t),
115 /* should be unreachable */
120 *buffer_size
= desired_size
;
126 net_marshal_func(char *buffer
, size_t *buffer_size
, void *retval
, va_list ap
,
134 size_t orig_buf_size
;
136 struct netent new_ne
;
137 size_t desired_size
, size
, aliases_size
;
141 switch ((enum nss_lookup_type
)cache_mdata
) {
143 name
= va_arg(ap
, char *);
146 net
= va_arg(ap
, uint32_t);
147 type
= va_arg(ap
, int);
152 /* should be unreachable */
156 ne
= va_arg(ap
, struct netent
*);
157 orig_buf
= va_arg(ap
, char *);
158 orig_buf_size
= va_arg(ap
, size_t);
160 desired_size
= _ALIGNBYTES
+ sizeof(struct netent
) + sizeof(char *);
161 if (ne
->n_name
!= NULL
)
162 desired_size
+= strlen(ne
->n_name
) + 1;
164 if (ne
->n_aliases
!= NULL
) {
166 for (alias
= ne
->n_aliases
; *alias
; ++alias
) {
167 desired_size
+= strlen(*alias
) + 1;
171 desired_size
+= _ALIGNBYTES
+
172 (aliases_size
+ 1) * sizeof(char *);
175 if (*buffer_size
< desired_size
) {
176 /* this assignment is here for future use */
177 *buffer_size
= desired_size
;
181 memcpy(&new_ne
, ne
, sizeof(struct netent
));
183 *buffer_size
= desired_size
;
184 memset(buffer
, 0, desired_size
);
185 p
= buffer
+ sizeof(struct netent
) + sizeof(char *);
186 memcpy(buffer
+ sizeof(struct netent
), &p
, sizeof(char *));
187 p
= (char *)_ALIGN(p
);
189 if (new_ne
.n_name
!= NULL
) {
190 size
= strlen(new_ne
.n_name
);
191 memcpy(p
, new_ne
.n_name
, size
);
196 if (new_ne
.n_aliases
!= NULL
) {
197 p
= (char *)_ALIGN(p
);
198 memcpy(p
, new_ne
.n_aliases
, sizeof(char *) * aliases_size
);
199 new_ne
.n_aliases
= (char **)p
;
200 p
+= sizeof(char *) * (aliases_size
+ 1);
202 for (alias
= new_ne
.n_aliases
; *alias
; ++alias
) {
203 size
= strlen(*alias
);
204 memcpy(p
, *alias
, size
);
210 memcpy(buffer
, &new_ne
, sizeof(struct netent
));
215 net_unmarshal_func(char *buffer
, size_t buffer_size
, void *retval
, va_list ap
,
223 size_t orig_buf_size
;
229 switch ((enum nss_lookup_type
)cache_mdata
) {
231 name
= va_arg(ap
, char *);
234 net
= va_arg(ap
, uint32_t);
235 type
= va_arg(ap
, int);
240 /* should be unreachable */
244 ne
= va_arg(ap
, struct netent
*);
245 orig_buf
= va_arg(ap
, char *);
246 orig_buf_size
= va_arg(ap
, size_t);
247 ret_errno
= va_arg(ap
, int *);
250 buffer_size
- sizeof(struct netent
) - sizeof(char *)) {
255 memcpy(ne
, buffer
, sizeof(struct netent
));
256 memcpy(&p
, buffer
+ sizeof(struct netent
), sizeof(char *));
258 orig_buf
= (char *)_ALIGN(orig_buf
);
259 memcpy(orig_buf
, buffer
+ sizeof(struct netent
) + sizeof(char *) +
260 _ALIGN(p
) - (size_t)p
,
261 buffer_size
- sizeof(struct netent
) - sizeof(char *) -
262 _ALIGN(p
) + (size_t)p
);
263 p
= (char *)_ALIGN(p
);
265 NS_APPLY_OFFSET(ne
->n_name
, orig_buf
, p
, char *);
266 if (ne
->n_aliases
!= NULL
) {
267 NS_APPLY_OFFSET(ne
->n_aliases
, orig_buf
, p
, char **);
269 for (alias
= ne
->n_aliases
; *alias
; ++alias
)
270 NS_APPLY_OFFSET(*alias
, orig_buf
, p
, char *);
274 *((struct netent
**)retval
) = ne
;
278 #endif /* NS_CACHING */
281 netent_data_free(void *ptr
)
283 struct netent_data
*ned
= ptr
;
293 netdata_free(void *ptr
)
299 __copy_netent(struct netent
*ne
, struct netent
*nptr
, char *buf
, size_t buflen
)
305 /* Find out the amount of space required to store the answer. */
306 numptr
= 1; /* NULL ptr */
307 len
= (char *)ALIGN(buf
) - buf
;
308 for (i
= 0; ne
->n_aliases
[i
]; i
++, numptr
++) {
309 len
+= strlen(ne
->n_aliases
[i
]) + 1;
311 len
+= strlen(ne
->n_name
) + 1;
312 len
+= numptr
* sizeof(char*);
314 if (len
> (int)buflen
) {
319 /* copy net value and type */
320 nptr
->n_addrtype
= ne
->n_addrtype
;
321 nptr
->n_net
= ne
->n_net
;
323 cp
= (char *)ALIGN(buf
) + numptr
* sizeof(char *);
325 /* copy official name */
326 n
= strlen(ne
->n_name
) + 1;
327 strcpy(cp
, ne
->n_name
);
332 nptr
->n_aliases
= (char **)ALIGN(buf
);
333 for (i
= 0 ; ne
->n_aliases
[i
]; i
++) {
334 n
= strlen(ne
->n_aliases
[i
]) + 1;
335 strcpy(cp
, ne
->n_aliases
[i
]);
336 nptr
->n_aliases
[i
] = cp
;
339 nptr
->n_aliases
[i
] = NULL
;
345 getnetbyname_r(const char *name
, struct netent
*ne
, char *buffer
,
346 size_t buflen
, struct netent
**result
, int *h_errorp
)
349 static const nss_cache_info cache_info
=
350 NS_COMMON_CACHE_INFO_INITIALIZER(
351 networks
, (void *)nss_lt_name
,
352 net_id_func
, net_marshal_func
, net_unmarshal_func
);
354 static const ns_dtab dtab
[] = {
355 NS_FILES_CB(_ht_getnetbyname
, NULL
)
356 { NSSRC_DNS
, _dns_getnetbyname
, NULL
},
357 NS_NIS_CB(_nis_getnetbyname
, NULL
) /* force -DHESIOD */
359 NS_CACHE_CB(&cache_info
)
365 rval
= _nsdispatch((void *)result
, dtab
, NSDB_NETWORKS
,
366 "getnetbyname_r", default_src
, name
, ne
, buffer
, buflen
,
367 &ret_errno
, h_errorp
);
369 return ((rval
== NS_SUCCESS
) ? 0 : -1);
373 getnetbyaddr_r(uint32_t addr
, int af
, struct netent
*ne
, char *buffer
,
374 size_t buflen
, struct netent
**result
, int *h_errorp
)
377 static const nss_cache_info cache_info
=
378 NS_COMMON_CACHE_INFO_INITIALIZER(
379 networks
, (void *)nss_lt_id
,
380 net_id_func
, net_marshal_func
, net_unmarshal_func
);
382 static const ns_dtab dtab
[] = {
383 NS_FILES_CB(_ht_getnetbyaddr
, NULL
)
384 { NSSRC_DNS
, _dns_getnetbyaddr
, NULL
},
385 NS_NIS_CB(_nis_getnetbyaddr
, NULL
) /* force -DHESIOD */
387 NS_CACHE_CB(&cache_info
)
393 rval
= _nsdispatch((void *)result
, dtab
, NSDB_NETWORKS
,
394 "getnetbyaddr_r", default_src
, addr
, af
, ne
, buffer
, buflen
,
395 &ret_errno
, h_errorp
);
397 return ((rval
== NS_SUCCESS
) ? 0 : -1);
401 getnetbyname(const char *name
)
407 if ((nd
= __netdata_init()) == NULL
)
409 if (getnetbyname_r(name
, &nd
->net
, nd
->data
, sizeof(nd
->data
), &rval
,
416 getnetbyaddr(uint32_t addr
, int af
)
422 if ((nd
= __netdata_init()) == NULL
)
424 if (getnetbyaddr_r(addr
, af
, &nd
->net
, nd
->data
, sizeof(nd
->data
),
425 &rval
, &ret_h_errno
) != 0)
431 setnetent(int stayopen
)
433 struct netent_data
*ned
;
435 if ((ned
= __netent_data_init()) == NULL
)
437 _setnethtent(stayopen
, ned
);
438 _setnetdnsent(stayopen
);
444 struct netent_data
*ned
;
446 if ((ned
= __netent_data_init()) == NULL
)