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: stable/11/lib/libc/net/getnetnamadr.c 360415 2020-04-27 23:49:13Z brooks $"); 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 49298830Spfg/* Network lookup order if nsswitch.conf is broken or nonexistent */ 50157779Sumestatic const ns_src default_src[] = { 5165532Snectar { NSSRC_FILES, NS_SUCCESS }, 5265532Snectar { NSSRC_DNS, NS_SUCCESS }, 5365532Snectar { 0 } 543070Spst}; 553070Spst 56157779SumeNETDB_THREAD_ALLOC(netent_data) 57157779SumeNETDB_THREAD_ALLOC(netdata) 58145626Sume 59158115Sume#ifdef NS_CACHING 60158115Sumestatic int 61158115Sumenet_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata) 62158115Sume{ 63158115Sume char *name; 64158115Sume uint32_t net; 65158115Sume int type; 66158115Sume 67158115Sume size_t desired_size, size; 68158115Sume enum nss_lookup_type lookup_type; 69158115Sume int res = NS_UNAVAIL; 70158115Sume 71360415Sbrooks lookup_type = (enum nss_lookup_type)(uintptr_t)cache_mdata; 72158115Sume switch (lookup_type) { 73158115Sume case nss_lt_name: 74158115Sume name = va_arg(ap, char *); 75158115Sume 76158115Sume size = strlen(name); 77158115Sume desired_size = sizeof(enum nss_lookup_type) + size + 1; 78158115Sume if (desired_size > *buffer_size) { 79158115Sume res = NS_RETURN; 80158115Sume goto fin; 81158115Sume } 82158115Sume 83158115Sume memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 84158115Sume memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1); 85158115Sume 86158115Sume res = NS_SUCCESS; 87158115Sume break; 88158115Sume case nss_lt_id: 89158115Sume net = va_arg(ap, uint32_t); 90158115Sume type = va_arg(ap, int); 91158115Sume 92158115Sume desired_size = sizeof(enum nss_lookup_type) + 93158115Sume sizeof(uint32_t) + sizeof(int); 94158115Sume if (desired_size > *buffer_size) { 95158115Sume res = NS_RETURN; 96158115Sume goto fin; 97158115Sume } 98158115Sume 99158115Sume memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 100158115Sume memcpy(buffer + sizeof(enum nss_lookup_type), &net, 101158115Sume sizeof(uint32_t)); 102158115Sume memcpy(buffer + sizeof(enum nss_lookup_type) + sizeof(uint32_t), 103158115Sume &type, sizeof(int)); 104158115Sume 105158115Sume res = NS_SUCCESS; 106158115Sume break; 107158115Sume default: 108158115Sume /* should be unreachable */ 109158115Sume return (NS_UNAVAIL); 110158115Sume } 111158115Sume 112158115Sumefin: 113158115Sume *buffer_size = desired_size; 114158115Sume return (res); 115158115Sume} 116158115Sume 117158115Sume 118158115Sumestatic int 119158115Sumenet_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, 120158115Sume void *cache_mdata) 121158115Sume{ 122158115Sume char *name; 123158115Sume uint32_t net; 124158115Sume int type; 125158115Sume struct netent *ne; 126158115Sume char *orig_buf; 127158115Sume size_t orig_buf_size; 128158115Sume 129158115Sume struct netent new_ne; 130158115Sume size_t desired_size, size, aliases_size; 131158115Sume char *p; 132158115Sume char **alias; 133158115Sume 134360415Sbrooks switch ((enum nss_lookup_type)(uintptr_t)cache_mdata) { 135158115Sume case nss_lt_name: 136158115Sume name = va_arg(ap, char *); 137158115Sume break; 138158115Sume case nss_lt_id: 139158115Sume net = va_arg(ap, uint32_t); 140158115Sume type = va_arg(ap, int); 141158115Sume break; 142158115Sume case nss_lt_all: 143158115Sume break; 144158115Sume default: 145158115Sume /* should be unreachable */ 146158115Sume return (NS_UNAVAIL); 147158115Sume } 148158115Sume 149158115Sume ne = va_arg(ap, struct netent *); 150158115Sume orig_buf = va_arg(ap, char *); 151158115Sume orig_buf_size = va_arg(ap, size_t); 152158115Sume 153158115Sume desired_size = _ALIGNBYTES + sizeof(struct netent) + sizeof(char *); 154158115Sume if (ne->n_name != NULL) 155158115Sume desired_size += strlen(ne->n_name) + 1; 156158115Sume 157158115Sume if (ne->n_aliases != NULL) { 158158115Sume aliases_size = 0; 159158115Sume for (alias = ne->n_aliases; *alias; ++alias) { 160158115Sume desired_size += strlen(*alias) + 1; 161158115Sume ++aliases_size; 162158115Sume } 163158115Sume 164158115Sume desired_size += _ALIGNBYTES + 165158115Sume (aliases_size + 1) * sizeof(char *); 166158115Sume } 167158115Sume 168158115Sume if (*buffer_size < desired_size) { 169158115Sume /* this assignment is here for future use */ 170158115Sume *buffer_size = desired_size; 171158115Sume return (NS_RETURN); 172158115Sume } 173158115Sume 174158115Sume memcpy(&new_ne, ne, sizeof(struct netent)); 175158115Sume 176158115Sume *buffer_size = desired_size; 177158115Sume memset(buffer, 0, desired_size); 178158115Sume p = buffer + sizeof(struct netent) + sizeof(char *); 179158115Sume memcpy(buffer + sizeof(struct netent), &p, sizeof(char *)); 180158115Sume p = (char *)_ALIGN(p); 181158115Sume 182158115Sume if (new_ne.n_name != NULL) { 183158115Sume size = strlen(new_ne.n_name); 184158115Sume memcpy(p, new_ne.n_name, size); 185158115Sume new_ne.n_name = p; 186158115Sume p += size + 1; 187158115Sume } 188158115Sume 189158115Sume if (new_ne.n_aliases != NULL) { 190158115Sume p = (char *)_ALIGN(p); 191158115Sume memcpy(p, new_ne.n_aliases, sizeof(char *) * aliases_size); 192158115Sume new_ne.n_aliases = (char **)p; 193158115Sume p += sizeof(char *) * (aliases_size + 1); 194158115Sume 195158115Sume for (alias = new_ne.n_aliases; *alias; ++alias) { 196158115Sume size = strlen(*alias); 197158115Sume memcpy(p, *alias, size); 198158115Sume *alias = p; 199158115Sume p += size + 1; 200158115Sume } 201158115Sume } 202158115Sume 203158115Sume memcpy(buffer, &new_ne, sizeof(struct netent)); 204158115Sume return (NS_SUCCESS); 205158115Sume} 206158115Sume 207158115Sumestatic int 208158115Sumenet_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap, 209158115Sume void *cache_mdata) 210158115Sume{ 211158115Sume char *name; 212158115Sume uint32_t net; 213158115Sume int type; 214158115Sume struct netent *ne; 215158115Sume char *orig_buf; 216158115Sume size_t orig_buf_size; 217158115Sume int *ret_errno; 218158115Sume 219158115Sume char *p; 220158115Sume char **alias; 221158115Sume 222360415Sbrooks switch ((enum nss_lookup_type)(uintptr_t)cache_mdata) { 223158115Sume case nss_lt_name: 224158115Sume name = va_arg(ap, char *); 225158115Sume break; 226158115Sume case nss_lt_id: 227158115Sume net = va_arg(ap, uint32_t); 228158115Sume type = va_arg(ap, int); 229158115Sume break; 230158115Sume case nss_lt_all: 231158115Sume break; 232158115Sume default: 233158115Sume /* should be unreachable */ 234158115Sume return (NS_UNAVAIL); 235158115Sume } 236158115Sume 237158115Sume ne = va_arg(ap, struct netent *); 238158115Sume orig_buf = va_arg(ap, char *); 239158115Sume orig_buf_size = va_arg(ap, size_t); 240158115Sume ret_errno = va_arg(ap, int *); 241158115Sume 242158115Sume if (orig_buf_size < 243158115Sume buffer_size - sizeof(struct netent) - sizeof(char *)) { 244158115Sume *ret_errno = ERANGE; 245158115Sume return (NS_RETURN); 246158115Sume } 247158115Sume 248158115Sume memcpy(ne, buffer, sizeof(struct netent)); 249158115Sume memcpy(&p, buffer + sizeof(struct netent), sizeof(char *)); 250158115Sume 251158115Sume orig_buf = (char *)_ALIGN(orig_buf); 252158115Sume memcpy(orig_buf, buffer + sizeof(struct netent) + sizeof(char *) + 253158115Sume _ALIGN(p) - (size_t)p, 254158115Sume buffer_size - sizeof(struct netent) - sizeof(char *) - 255158115Sume _ALIGN(p) + (size_t)p); 256158115Sume p = (char *)_ALIGN(p); 257158115Sume 258158115Sume NS_APPLY_OFFSET(ne->n_name, orig_buf, p, char *); 259158115Sume if (ne->n_aliases != NULL) { 260158115Sume NS_APPLY_OFFSET(ne->n_aliases, orig_buf, p, char **); 261158115Sume 262158115Sume for (alias = ne->n_aliases; *alias; ++alias) 263158115Sume NS_APPLY_OFFSET(*alias, orig_buf, p, char *); 264158115Sume } 265158115Sume 266158115Sume if (retval != NULL) 267158115Sume *((struct netent **)retval) = ne; 268158115Sume 269158115Sume return (NS_SUCCESS); 270158115Sume} 271158115Sume#endif /* NS_CACHING */ 272158115Sume 273145626Sumestatic void 274157779Sumenetent_data_free(void *ptr) 2753070Spst{ 276157779Sume struct netent_data *ned = ptr; 277145626Sume 278157779Sume if (ned == NULL) 279145626Sume return; 280157779Sume ned->stayopen = 0; 281157779Sume _endnethtent(ned); 282157779Sume free(ned); 283145626Sume} 284145626Sume 285145626Sumestatic void 286157779Sumenetdata_free(void *ptr) 287145626Sume{ 288157779Sume free(ptr); 289145626Sume} 290145626Sume 291157779Sumeint 292157779Sume__copy_netent(struct netent *ne, struct netent *nptr, char *buf, size_t buflen) 293145626Sume{ 294157779Sume char *cp; 295157779Sume int i, n; 296157779Sume int numptr, len; 297145626Sume 298157779Sume /* Find out the amount of space required to store the answer. */ 299157779Sume numptr = 1; /* NULL ptr */ 300157779Sume len = (char *)ALIGN(buf) - buf; 301157779Sume for (i = 0; ne->n_aliases[i]; i++, numptr++) { 302157779Sume len += strlen(ne->n_aliases[i]) + 1; 303157779Sume } 304157779Sume len += strlen(ne->n_name) + 1; 305157779Sume len += numptr * sizeof(char*); 306157779Sume 307157779Sume if (len > (int)buflen) { 308157779Sume errno = ERANGE; 309157779Sume return (-1); 310157779Sume } 311157779Sume 312157779Sume /* copy net value and type */ 313157779Sume nptr->n_addrtype = ne->n_addrtype; 314157779Sume nptr->n_net = ne->n_net; 315157779Sume 316157779Sume cp = (char *)ALIGN(buf) + numptr * sizeof(char *); 317157779Sume 318157779Sume /* copy official name */ 319157779Sume n = strlen(ne->n_name) + 1; 320157779Sume strcpy(cp, ne->n_name); 321157779Sume nptr->n_name = cp; 322157779Sume cp += n; 323157779Sume 324157779Sume /* copy aliases */ 325157779Sume nptr->n_aliases = (char **)ALIGN(buf); 326157779Sume for (i = 0 ; ne->n_aliases[i]; i++) { 327157779Sume n = strlen(ne->n_aliases[i]) + 1; 328157779Sume strcpy(cp, ne->n_aliases[i]); 329157779Sume nptr->n_aliases[i] = cp; 330157779Sume cp += n; 331157779Sume } 332157779Sume nptr->n_aliases[i] = NULL; 333157779Sume 334157779Sume return (0); 335145626Sume} 336145626Sume 337145626Sumeint 338157779Sumegetnetbyname_r(const char *name, struct netent *ne, char *buffer, 339157779Sume size_t buflen, struct netent **result, int *h_errorp) 340145626Sume{ 341158115Sume#ifdef NS_CACHING 342158115Sume static const nss_cache_info cache_info = 343158115Sume NS_COMMON_CACHE_INFO_INITIALIZER( 344158115Sume networks, (void *)nss_lt_name, 345158115Sume net_id_func, net_marshal_func, net_unmarshal_func); 346158115Sume#endif 34765532Snectar static const ns_dtab dtab[] = { 34865532Snectar NS_FILES_CB(_ht_getnetbyname, NULL) 34965532Snectar { NSSRC_DNS, _dns_getnetbyname, NULL }, 35065532Snectar NS_NIS_CB(_nis_getnetbyname, NULL) /* force -DHESIOD */ 351158115Sume#ifdef NS_CACHING 352158115Sume NS_CACHE_CB(&cache_info) 353158115Sume#endif 35465532Snectar { 0 } 355145626Sume }; 356211276Sume int rval, ret_errno = 0; 35765532Snectar 358157779Sume rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS, 359157779Sume "getnetbyname_r", default_src, name, ne, buffer, buflen, 360157779Sume &ret_errno, h_errorp); 361145626Sume 362211276Sume if (rval != NS_SUCCESS) { 363211276Sume errno = ret_errno; 364211276Sume return ((ret_errno != 0) ? ret_errno : -1); 365211276Sume } 366211276Sume return (0); 3673070Spst} 3683070Spst 369145626Sumeint 370157779Sumegetnetbyaddr_r(uint32_t addr, int af, struct netent *ne, char *buffer, 371157779Sume size_t buflen, struct netent **result, int *h_errorp) 3723070Spst{ 373158115Sume#ifdef NS_CACHING 374158115Sume static const nss_cache_info cache_info = 375158115Sume NS_COMMON_CACHE_INFO_INITIALIZER( 376158115Sume networks, (void *)nss_lt_id, 377158115Sume net_id_func, net_marshal_func, net_unmarshal_func); 378158115Sume#endif 37965532Snectar static const ns_dtab dtab[] = { 38065532Snectar NS_FILES_CB(_ht_getnetbyaddr, NULL) 38165532Snectar { NSSRC_DNS, _dns_getnetbyaddr, NULL }, 38265532Snectar NS_NIS_CB(_nis_getnetbyaddr, NULL) /* force -DHESIOD */ 383158115Sume#ifdef NS_CACHING 384158115Sume NS_CACHE_CB(&cache_info) 385158115Sume#endif 38665532Snectar { 0 } 387145626Sume }; 388211276Sume int rval, ret_errno = 0; 3893070Spst 390157779Sume rval = _nsdispatch((void *)result, dtab, NSDB_NETWORKS, 391157779Sume "getnetbyaddr_r", default_src, addr, af, ne, buffer, buflen, 392157779Sume &ret_errno, h_errorp); 39365532Snectar 394211276Sume if (rval != NS_SUCCESS) { 395211276Sume errno = ret_errno; 396211276Sume return ((ret_errno != 0) ? ret_errno : -1); 397211276Sume } 398211276Sume return (0); 3993070Spst} 4003070Spst 401145626Sumestruct netent * 402145626Sumegetnetbyname(const char *name) 403145626Sume{ 404145626Sume struct netdata *nd; 405157779Sume struct netent *rval; 406157779Sume int ret_h_errno; 407145626Sume 408145626Sume if ((nd = __netdata_init()) == NULL) 409157779Sume return (NULL); 410157779Sume if (getnetbyname_r(name, &nd->net, nd->data, sizeof(nd->data), &rval, 411157779Sume &ret_h_errno) != 0) 412157779Sume return (NULL); 413157779Sume return (rval); 414145626Sume} 415145626Sume 416145626Sumestruct netent * 417146244Sumegetnetbyaddr(uint32_t addr, int af) 418145626Sume{ 419145626Sume struct netdata *nd; 420157779Sume struct netent *rval; 421157779Sume int ret_h_errno; 422145626Sume 423145626Sume if ((nd = __netdata_init()) == NULL) 424157779Sume return (NULL); 425157779Sume if (getnetbyaddr_r(addr, af, &nd->net, nd->data, sizeof(nd->data), 426157779Sume &rval, &ret_h_errno) != 0) 427157779Sume return (NULL); 428157779Sume return (rval); 429145626Sume} 430145626Sume 431145626Sumevoid 432145626Sumesetnetent(int stayopen) 433145626Sume{ 434157779Sume struct netent_data *ned; 435145626Sume 436157779Sume if ((ned = __netent_data_init()) == NULL) 437145626Sume return; 438157779Sume _setnethtent(stayopen, ned); 439157779Sume _setnetdnsent(stayopen); 440145626Sume} 441145626Sume 442145626Sumevoid 443145626Sumeendnetent(void) 444145626Sume{ 445157779Sume struct netent_data *ned; 446145626Sume 447157779Sume if ((ned = __netent_data_init()) == NULL) 448145626Sume return; 449157779Sume _endnethtent(ned); 450157779Sume _endnetdnsent(); 451145626Sume} 452