getnetnamadr.c revision 158115
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: head/lib/libc/net/getnetnamadr.c 158115 2006-04-28 12:03:38Z ume $"); 283070Spst 29113977Snectar#include "namespace.h" 30145626Sume#include "reentrant.h" 313070Spst#include <sys/param.h> 323070Spst#include <sys/socket.h> 333070Spst#include <netinet/in.h> 343070Spst#include <arpa/inet.h> 353070Spst#include <netdb.h> 363070Spst#include <stdio.h> 373070Spst#include <ctype.h> 38157779Sume#include <errno.h> 39145626Sume#include <stdlib.h> 403070Spst#include <string.h> 4165532Snectar#include <stdarg.h> 4265532Snectar#include <nsswitch.h> 43113977Snectar#include "un-namespace.h" 44145602Sume#include "netdb_private.h" 45158115Sume#ifdef NS_CACHING 46158115Sume#include "nscache.h" 47158115Sume#endif 483070Spst 4965532Snectarextern int _ht_getnetbyname(void *, void *, va_list); 5065532Snectarextern int _dns_getnetbyname(void *, void *, va_list); 5165532Snectarextern int _nis_getnetbyname(void *, void *, va_list); 5265532Snectarextern int _ht_getnetbyaddr(void *, void *, va_list); 5365532Snectarextern int _dns_getnetbyaddr(void *, void *, va_list); 5465532Snectarextern int _nis_getnetbyaddr(void *, void *, va_list); 553070Spst 5665532Snectar/* Network lookup order if nsswitch.conf is broken or nonexistant */ 57157779Sumestatic const ns_src default_src[] = { 5865532Snectar { NSSRC_FILES, NS_SUCCESS }, 5965532Snectar { NSSRC_DNS, NS_SUCCESS }, 6065532Snectar { 0 } 613070Spst}; 623070Spst 63157779SumeNETDB_THREAD_ALLOC(netent_data) 64157779SumeNETDB_THREAD_ALLOC(netdata) 65145626Sume 66158115Sume#ifdef NS_CACHING 67158115Sumestatic int 68158115Sumenet_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata) 69158115Sume{ 70158115Sume char *name; 71158115Sume uint32_t net; 72158115Sume int type; 73158115Sume 74158115Sume size_t desired_size, size; 75158115Sume enum nss_lookup_type lookup_type; 76158115Sume int res = NS_UNAVAIL; 77158115Sume 78158115Sume lookup_type = (enum nss_lookup_type)cache_mdata; 79158115Sume switch (lookup_type) { 80158115Sume case nss_lt_name: 81158115Sume name = va_arg(ap, char *); 82158115Sume 83158115Sume size = strlen(name); 84158115Sume desired_size = sizeof(enum nss_lookup_type) + size + 1; 85158115Sume if (desired_size > *buffer_size) { 86158115Sume res = NS_RETURN; 87158115Sume goto fin; 88158115Sume } 89158115Sume 90158115Sume memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 91158115Sume memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1); 92158115Sume 93158115Sume res = NS_SUCCESS; 94158115Sume break; 95158115Sume case nss_lt_id: 96158115Sume net = va_arg(ap, uint32_t); 97158115Sume type = va_arg(ap, int); 98158115Sume 99158115Sume desired_size = sizeof(enum nss_lookup_type) + 100158115Sume sizeof(uint32_t) + sizeof(int); 101158115Sume if (desired_size > *buffer_size) { 102158115Sume res = NS_RETURN; 103158115Sume goto fin; 104158115Sume } 105158115Sume 106158115Sume memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 107158115Sume memcpy(buffer + sizeof(enum nss_lookup_type), &net, 108158115Sume sizeof(uint32_t)); 109158115Sume memcpy(buffer + sizeof(enum nss_lookup_type) + sizeof(uint32_t), 110158115Sume &type, sizeof(int)); 111158115Sume 112158115Sume res = NS_SUCCESS; 113158115Sume break; 114158115Sume default: 115158115Sume /* should be unreachable */ 116158115Sume return (NS_UNAVAIL); 117158115Sume } 118158115Sume 119158115Sumefin: 120158115Sume *buffer_size = desired_size; 121158115Sume return (res); 122158115Sume} 123158115Sume 124158115Sume 125158115Sumestatic int 126158115Sumenet_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, 127158115Sume void *cache_mdata) 128158115Sume{ 129158115Sume char *name; 130158115Sume uint32_t net; 131158115Sume int type; 132158115Sume struct netent *ne; 133158115Sume char *orig_buf; 134158115Sume size_t orig_buf_size; 135158115Sume 136158115Sume struct netent new_ne; 137158115Sume size_t desired_size, size, aliases_size; 138158115Sume char *p; 139158115Sume char **alias; 140158115Sume 141158115Sume switch ((enum nss_lookup_type)cache_mdata) { 142158115Sume case nss_lt_name: 143158115Sume name = va_arg(ap, char *); 144158115Sume break; 145158115Sume case nss_lt_id: 146158115Sume net = va_arg(ap, uint32_t); 147158115Sume type = va_arg(ap, int); 148158115Sume break; 149158115Sume case nss_lt_all: 150158115Sume break; 151158115Sume default: 152158115Sume /* should be unreachable */ 153158115Sume return (NS_UNAVAIL); 154158115Sume } 155158115Sume 156158115Sume ne = va_arg(ap, struct netent *); 157158115Sume orig_buf = va_arg(ap, char *); 158158115Sume orig_buf_size = va_arg(ap, size_t); 159158115Sume 160158115Sume desired_size = _ALIGNBYTES + sizeof(struct netent) + sizeof(char *); 161158115Sume if (ne->n_name != NULL) 162158115Sume desired_size += strlen(ne->n_name) + 1; 163158115Sume 164158115Sume if (ne->n_aliases != NULL) { 165158115Sume aliases_size = 0; 166158115Sume for (alias = ne->n_aliases; *alias; ++alias) { 167158115Sume desired_size += strlen(*alias) + 1; 168158115Sume ++aliases_size; 169158115Sume } 170158115Sume 171158115Sume desired_size += _ALIGNBYTES + 172158115Sume (aliases_size + 1) * sizeof(char *); 173158115Sume } 174158115Sume 175158115Sume if (*buffer_size < desired_size) { 176158115Sume /* this assignment is here for future use */ 177158115Sume *buffer_size = desired_size; 178158115Sume return (NS_RETURN); 179158115Sume } 180158115Sume 181158115Sume memcpy(&new_ne, ne, sizeof(struct netent)); 182158115Sume 183158115Sume *buffer_size = desired_size; 184158115Sume memset(buffer, 0, desired_size); 185158115Sume p = buffer + sizeof(struct netent) + sizeof(char *); 186158115Sume memcpy(buffer + sizeof(struct netent), &p, sizeof(char *)); 187158115Sume p = (char *)_ALIGN(p); 188158115Sume 189158115Sume if (new_ne.n_name != NULL) { 190158115Sume size = strlen(new_ne.n_name); 191158115Sume memcpy(p, new_ne.n_name, size); 192158115Sume new_ne.n_name = p; 193158115Sume p += size + 1; 194158115Sume } 195158115Sume 196158115Sume if (new_ne.n_aliases != NULL) { 197158115Sume p = (char *)_ALIGN(p); 198158115Sume memcpy(p, new_ne.n_aliases, sizeof(char *) * aliases_size); 199158115Sume new_ne.n_aliases = (char **)p; 200158115Sume p += sizeof(char *) * (aliases_size + 1); 201158115Sume 202158115Sume for (alias = new_ne.n_aliases; *alias; ++alias) { 203158115Sume size = strlen(*alias); 204158115Sume memcpy(p, *alias, size); 205158115Sume *alias = p; 206158115Sume p += size + 1; 207158115Sume } 208158115Sume } 209158115Sume 210158115Sume memcpy(buffer, &new_ne, sizeof(struct netent)); 211158115Sume return (NS_SUCCESS); 212158115Sume} 213158115Sume 214158115Sumestatic int 215158115Sumenet_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap, 216158115Sume void *cache_mdata) 217158115Sume{ 218158115Sume char *name; 219158115Sume uint32_t net; 220158115Sume int type; 221158115Sume struct netent *ne; 222158115Sume char *orig_buf; 223158115Sume size_t orig_buf_size; 224158115Sume int *ret_errno; 225158115Sume 226158115Sume char *p; 227158115Sume char **alias; 228158115Sume 229158115Sume switch ((enum nss_lookup_type)cache_mdata) { 230158115Sume case nss_lt_name: 231158115Sume name = va_arg(ap, char *); 232158115Sume break; 233158115Sume case nss_lt_id: 234158115Sume net = va_arg(ap, uint32_t); 235158115Sume type = va_arg(ap, int); 236158115Sume break; 237158115Sume case nss_lt_all: 238158115Sume break; 239158115Sume default: 240158115Sume /* should be unreachable */ 241158115Sume return (NS_UNAVAIL); 242158115Sume } 243158115Sume 244158115Sume ne = va_arg(ap, struct netent *); 245158115Sume orig_buf = va_arg(ap, char *); 246158115Sume orig_buf_size = va_arg(ap, size_t); 247158115Sume ret_errno = va_arg(ap, int *); 248158115Sume 249158115Sume if (orig_buf_size < 250158115Sume buffer_size - sizeof(struct netent) - sizeof(char *)) { 251158115Sume *ret_errno = ERANGE; 252158115Sume return (NS_RETURN); 253158115Sume } 254158115Sume 255158115Sume memcpy(ne, buffer, sizeof(struct netent)); 256158115Sume memcpy(&p, buffer + sizeof(struct netent), sizeof(char *)); 257158115Sume 258158115Sume orig_buf = (char *)_ALIGN(orig_buf); 259158115Sume memcpy(orig_buf, buffer + sizeof(struct netent) + sizeof(char *) + 260158115Sume _ALIGN(p) - (size_t)p, 261158115Sume buffer_size - sizeof(struct netent) - sizeof(char *) - 262158115Sume _ALIGN(p) + (size_t)p); 263158115Sume p = (char *)_ALIGN(p); 264158115Sume 265158115Sume NS_APPLY_OFFSET(ne->n_name, orig_buf, p, char *); 266158115Sume if (ne->n_aliases != NULL) { 267158115Sume NS_APPLY_OFFSET(ne->n_aliases, orig_buf, p, char **); 268158115Sume 269158115Sume for (alias = ne->n_aliases; *alias; ++alias) 270158115Sume NS_APPLY_OFFSET(*alias, orig_buf, p, char *); 271158115Sume } 272158115Sume 273158115Sume if (retval != NULL) 274158115Sume *((struct netent **)retval) = ne; 275158115Sume 276158115Sume return (NS_SUCCESS); 277158115Sume} 278158115Sume#endif /* NS_CACHING */ 279158115Sume 280145626Sumestatic void 281157779Sumenetent_data_free(void *ptr) 2823070Spst{ 283157779Sume struct netent_data *ned = ptr; 284145626Sume 285157779Sume if (ned == NULL) 286145626Sume return; 287157779Sume ned->stayopen = 0; 288157779Sume _endnethtent(ned); 289157779Sume free(ned); 290145626Sume} 291145626Sume 292145626Sumestatic void 293157779Sumenetdata_free(void *ptr) 294145626Sume{ 295157779Sume free(ptr); 296145626Sume} 297145626Sume 298157779Sumeint 299157779Sume__copy_netent(struct netent *ne, struct netent *nptr, char *buf, size_t buflen) 300145626Sume{ 301157779Sume char *cp; 302157779Sume int i, n; 303157779Sume int numptr, len; 304145626Sume 305157779Sume /* Find out the amount of space required to store the answer. */ 306157779Sume numptr = 1; /* NULL ptr */ 307157779Sume len = (char *)ALIGN(buf) - buf; 308157779Sume for (i = 0; ne->n_aliases[i]; i++, numptr++) { 309157779Sume len += strlen(ne->n_aliases[i]) + 1; 310157779Sume } 311157779Sume len += strlen(ne->n_name) + 1; 312157779Sume len += numptr * sizeof(char*); 313157779Sume 314157779Sume if (len > (int)buflen) { 315157779Sume errno = ERANGE; 316157779Sume return (-1); 317157779Sume } 318157779Sume 319157779Sume /* copy net value and type */ 320157779Sume nptr->n_addrtype = ne->n_addrtype; 321157779Sume nptr->n_net = ne->n_net; 322157779Sume 323157779Sume cp = (char *)ALIGN(buf) + numptr * sizeof(char *); 324157779Sume 325157779Sume /* copy official name */ 326157779Sume n = strlen(ne->n_name) + 1; 327157779Sume strcpy(cp, ne->n_name); 328157779Sume nptr->n_name = cp; 329157779Sume cp += n; 330157779Sume 331157779Sume /* copy aliases */ 332157779Sume nptr->n_aliases = (char **)ALIGN(buf); 333157779Sume for (i = 0 ; ne->n_aliases[i]; i++) { 334157779Sume n = strlen(ne->n_aliases[i]) + 1; 335157779Sume strcpy(cp, ne->n_aliases[i]); 336157779Sume nptr->n_aliases[i] = cp; 337157779Sume cp += n; 338157779Sume } 339157779Sume nptr->n_aliases[i] = NULL; 340157779Sume 341157779Sume return (0); 342145626Sume} 343145626Sume 344145626Sumeint 345157779Sumegetnetbyname_r(const char *name, struct netent *ne, char *buffer, 346157779Sume size_t buflen, struct netent **result, int *h_errorp) 347145626Sume{ 348158115Sume#ifdef NS_CACHING 349158115Sume static const nss_cache_info cache_info = 350158115Sume NS_COMMON_CACHE_INFO_INITIALIZER( 351158115Sume networks, (void *)nss_lt_name, 352158115Sume net_id_func, net_marshal_func, net_unmarshal_func); 353158115Sume#endif 35465532Snectar static const ns_dtab dtab[] = { 35565532Snectar NS_FILES_CB(_ht_getnetbyname, NULL) 35665532Snectar { NSSRC_DNS, _dns_getnetbyname, NULL }, 35765532Snectar NS_NIS_CB(_nis_getnetbyname, NULL) /* force -DHESIOD */ 358158115Sume#ifdef NS_CACHING 359158115Sume NS_CACHE_CB(&cache_info) 360158115Sume#endif 36165532Snectar { 0 } 362145626Sume }; 363158115Sume int rval, ret_errno; 36465532Snectar 365157779Sume rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS, 366157779Sume "getnetbyname_r", default_src, name, ne, buffer, buflen, 367157779Sume &ret_errno, h_errorp); 368145626Sume 369157779Sume return ((rval == NS_SUCCESS) ? 0 : -1); 3703070Spst} 3713070Spst 372145626Sumeint 373157779Sumegetnetbyaddr_r(uint32_t addr, int af, struct netent *ne, char *buffer, 374157779Sume size_t buflen, struct netent **result, int *h_errorp) 3753070Spst{ 376158115Sume#ifdef NS_CACHING 377158115Sume static const nss_cache_info cache_info = 378158115Sume NS_COMMON_CACHE_INFO_INITIALIZER( 379158115Sume networks, (void *)nss_lt_id, 380158115Sume net_id_func, net_marshal_func, net_unmarshal_func); 381158115Sume#endif 38265532Snectar static const ns_dtab dtab[] = { 38365532Snectar NS_FILES_CB(_ht_getnetbyaddr, NULL) 38465532Snectar { NSSRC_DNS, _dns_getnetbyaddr, NULL }, 38565532Snectar NS_NIS_CB(_nis_getnetbyaddr, NULL) /* force -DHESIOD */ 386158115Sume#ifdef NS_CACHING 387158115Sume NS_CACHE_CB(&cache_info) 388158115Sume#endif 38965532Snectar { 0 } 390145626Sume }; 391158115Sume int rval, ret_errno; 3923070Spst 393157779Sume rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS, 394157779Sume "getnetbyaddr_r", default_src, addr, af, ne, buffer, buflen, 395157779Sume &ret_errno, h_errorp); 39665532Snectar 397157779Sume return ((rval == NS_SUCCESS) ? 0 : -1); 3983070Spst} 3993070Spst 400145626Sumestruct netent * 401145626Sumegetnetbyname(const char *name) 402145626Sume{ 403145626Sume struct netdata *nd; 404157779Sume struct netent *rval; 405157779Sume int ret_h_errno; 406145626Sume 407145626Sume if ((nd = __netdata_init()) == NULL) 408157779Sume return (NULL); 409157779Sume if (getnetbyname_r(name, &nd->net, nd->data, sizeof(nd->data), &rval, 410157779Sume &ret_h_errno) != 0) 411157779Sume return (NULL); 412157779Sume return (rval); 413145626Sume} 414145626Sume 415145626Sumestruct netent * 416146244Sumegetnetbyaddr(uint32_t addr, int af) 417145626Sume{ 418145626Sume struct netdata *nd; 419157779Sume struct netent *rval; 420157779Sume int ret_h_errno; 421145626Sume 422145626Sume if ((nd = __netdata_init()) == NULL) 423157779Sume return (NULL); 424157779Sume if (getnetbyaddr_r(addr, af, &nd->net, nd->data, sizeof(nd->data), 425157779Sume &rval, &ret_h_errno) != 0) 426157779Sume return (NULL); 427157779Sume return (rval); 428145626Sume} 429145626Sume 430145626Sumevoid 431145626Sumesetnetent(int stayopen) 432145626Sume{ 433157779Sume struct netent_data *ned; 434145626Sume 435157779Sume if ((ned = __netent_data_init()) == NULL) 436145626Sume return; 437157779Sume _setnethtent(stayopen, ned); 438157779Sume _setnetdnsent(stayopen); 439145626Sume} 440145626Sume 441145626Sumevoid 442145626Sumeendnetent(void) 443145626Sume{ 444157779Sume struct netent_data *ned; 445145626Sume 446157779Sume if ((ned = __netent_data_init()) == NULL) 447145626Sume return; 448157779Sume _endnethtent(ned); 449157779Sume _endnetdnsent(); 450145626Sume} 451