10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 22*132Srobinson 230Sstevel@tonic-gate /* 24*132Srobinson * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 250Sstevel@tonic-gate * Use is subject to license terms. 260Sstevel@tonic-gate */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 290Sstevel@tonic-gate 300Sstevel@tonic-gate /* 310Sstevel@tonic-gate * lib/libnsl/nss/gethostbyname_r.c 320Sstevel@tonic-gate * 330Sstevel@tonic-gate * gethostbyname_r() is defined in this file. It is implemented on top of 340Sstevel@tonic-gate * _get_hostserv_inetnetdir_byname() which is also used to implement 350Sstevel@tonic-gate * netdir_getbyname() for inet family transports. In turn the common code 360Sstevel@tonic-gate * uses the name service switch policy for "hosts" and "services" unless 370Sstevel@tonic-gate * the administrator chooses to bypass the name service switch by 380Sstevel@tonic-gate * specifying third-party supplied nametoaddr libs for inet transports 390Sstevel@tonic-gate * in /etc/netconfig. 400Sstevel@tonic-gate * 410Sstevel@tonic-gate * gethostbyaddr_r() is similarly related to _get_hostserv_inetnetdir_byaddr() 420Sstevel@tonic-gate * and netdir_getbyaddr(); 430Sstevel@tonic-gate * 440Sstevel@tonic-gate * The common code lives in netdir_inet.c. 450Sstevel@tonic-gate * 460Sstevel@tonic-gate * gethostent_r(), sethostent() and endhostent() are *not* implemented on top 470Sstevel@tonic-gate * of the common interface; they go straight to the switch and are 480Sstevel@tonic-gate * defined in gethostent_r.c. 490Sstevel@tonic-gate * 500Sstevel@tonic-gate * There is absolutely no data sharing, not even the stayopen flag or 510Sstevel@tonic-gate * enumeration state, between gethostbyYY_r() and gethostent_r(); 520Sstevel@tonic-gate */ 530Sstevel@tonic-gate 540Sstevel@tonic-gate #include <netdb.h> 550Sstevel@tonic-gate #include <netdir.h> 560Sstevel@tonic-gate #include <sys/types.h> 570Sstevel@tonic-gate #include <nss_netdir.h> 580Sstevel@tonic-gate #include <string.h> 590Sstevel@tonic-gate 600Sstevel@tonic-gate extern struct netconfig *__rpc_getconfip(); 610Sstevel@tonic-gate 620Sstevel@tonic-gate /* 630Sstevel@tonic-gate * h_errno POLICY: The frontends expect the name service 640Sstevel@tonic-gate * backends to modify the h_errno in "arg"; _switch_gethostbyYY_r() 650Sstevel@tonic-gate * will copy that over onto user's h_errnop pointer. This h_errno is 660Sstevel@tonic-gate * never used for "switching" -- status from nss_search serves 670Sstevel@tonic-gate * the purpose. There is no explicit zeroing in the case of success. 680Sstevel@tonic-gate */ 690Sstevel@tonic-gate 700Sstevel@tonic-gate extern struct hostent * 710Sstevel@tonic-gate _switch_gethostbyname_r(const char *nam, struct hostent *result, char *buffer, 720Sstevel@tonic-gate int buflen, int *h_errnop); 730Sstevel@tonic-gate 740Sstevel@tonic-gate extern struct hostent * 750Sstevel@tonic-gate _switch_gethostbyaddr_r(const char *addr, int length, int type, 760Sstevel@tonic-gate struct hostent *result, char *buffer, int buflen, int *h_errnop); 770Sstevel@tonic-gate 780Sstevel@tonic-gate #ifdef PIC 790Sstevel@tonic-gate struct hostent * 800Sstevel@tonic-gate _uncached_gethostbyname_r(const char *nam, struct hostent *result, 810Sstevel@tonic-gate char *buffer, int buflen, int *h_errnop) 820Sstevel@tonic-gate { 830Sstevel@tonic-gate return (_switch_gethostbyname_r(nam, result, 840Sstevel@tonic-gate buffer, buflen, h_errnop)); 850Sstevel@tonic-gate } 860Sstevel@tonic-gate 870Sstevel@tonic-gate struct hostent * 880Sstevel@tonic-gate _uncached_gethostbyaddr_r(const char *addr, int length, int type, 890Sstevel@tonic-gate struct hostent *result, char *buffer, int buflen, int *h_errnop) 900Sstevel@tonic-gate { 910Sstevel@tonic-gate return (_switch_gethostbyaddr_r(addr, length, type, 920Sstevel@tonic-gate result, buffer, buflen, h_errnop)); 930Sstevel@tonic-gate } 940Sstevel@tonic-gate 950Sstevel@tonic-gate #endif 960Sstevel@tonic-gate 970Sstevel@tonic-gate extern struct hostent * 980Sstevel@tonic-gate gethostbyname_r(const char *nam, struct hostent *result, char *buffer, 990Sstevel@tonic-gate int buflen, int *h_errnop); 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate extern struct hostent * 1020Sstevel@tonic-gate gethostbyaddr_r(const char *addr, int length, int type, 1030Sstevel@tonic-gate struct hostent *result, char *buffer, int buflen, int *h_errnop); 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate struct hostent * 1060Sstevel@tonic-gate gethostbyname_r(const char *nam, struct hostent *result, char *buffer, 1070Sstevel@tonic-gate int buflen, int *h_errnop) 1080Sstevel@tonic-gate { 1090Sstevel@tonic-gate struct netconfig *nconf; 1100Sstevel@tonic-gate struct nss_netdirbyname_in nssin; 1110Sstevel@tonic-gate union nss_netdirbyname_out nssout; 1120Sstevel@tonic-gate int neterr, dummy; 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate if (h_errnop == NULL) 1150Sstevel@tonic-gate h_errnop = &dummy; 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate if (strlen(nam) == 0) { 1180Sstevel@tonic-gate *h_errnop = HOST_NOT_FOUND; 119*132Srobinson return (NULL); 1200Sstevel@tonic-gate } 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate if ((nconf = __rpc_getconfip("udp")) == NULL && 1230Sstevel@tonic-gate (nconf = __rpc_getconfip("tcp")) == NULL) { 1240Sstevel@tonic-gate *h_errnop = NO_RECOVERY; 125*132Srobinson return (NULL); 1260Sstevel@tonic-gate } 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate nssin.op_t = NSS_HOST; 1290Sstevel@tonic-gate nssin.arg.nss.host.name = nam; 1300Sstevel@tonic-gate nssin.arg.nss.host.buf = buffer; 1310Sstevel@tonic-gate nssin.arg.nss.host.buflen = buflen; 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate nssout.nss.host.hent = result; 1340Sstevel@tonic-gate nssout.nss.host.herrno_p = h_errnop; 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate /* 1370Sstevel@tonic-gate * We pass in nconf and let the implementation of the long-named func 1380Sstevel@tonic-gate * decide whether to use the switch based on nc_nlookups. 1390Sstevel@tonic-gate */ 1400Sstevel@tonic-gate neterr = _get_hostserv_inetnetdir_byname(nconf, &nssin, &nssout); 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate (void) freenetconfigent(nconf); 143*132Srobinson if (neterr != ND_OK) 144*132Srobinson return (NULL); 1450Sstevel@tonic-gate return (nssout.nss.host.hent); 1460Sstevel@tonic-gate } 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate struct hostent * 1490Sstevel@tonic-gate gethostbyaddr_r(const char *addr, int length, int type, 1500Sstevel@tonic-gate struct hostent *result, char *buffer, int buflen, int *h_errnop) 1510Sstevel@tonic-gate { 1520Sstevel@tonic-gate struct netconfig *nconf; 1530Sstevel@tonic-gate struct nss_netdirbyaddr_in nssin; 1540Sstevel@tonic-gate union nss_netdirbyaddr_out nssout; 1550Sstevel@tonic-gate int neterr; 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate if (type != AF_INET) { 1580Sstevel@tonic-gate *h_errnop = HOST_NOT_FOUND; 159*132Srobinson return (NULL); 1600Sstevel@tonic-gate } 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate if ((nconf = __rpc_getconfip("udp")) == NULL && 1630Sstevel@tonic-gate (nconf = __rpc_getconfip("tcp")) == NULL) { 1640Sstevel@tonic-gate *h_errnop = NO_RECOVERY; 165*132Srobinson return (NULL); 1660Sstevel@tonic-gate } 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate nssin.op_t = NSS_HOST; 1690Sstevel@tonic-gate nssin.arg.nss.host.addr = addr; 1700Sstevel@tonic-gate nssin.arg.nss.host.len = length; 1710Sstevel@tonic-gate nssin.arg.nss.host.type = type; 1720Sstevel@tonic-gate nssin.arg.nss.host.buf = buffer; 1730Sstevel@tonic-gate nssin.arg.nss.host.buflen = buflen; 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate nssout.nss.host.hent = result; 1760Sstevel@tonic-gate nssout.nss.host.herrno_p = h_errnop; 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate /* 1790Sstevel@tonic-gate * We pass in nconf and let the implementation of this long-named func 1800Sstevel@tonic-gate * decide whether to use the switch based on nc_nlookups. 1810Sstevel@tonic-gate */ 1820Sstevel@tonic-gate neterr = _get_hostserv_inetnetdir_byaddr(nconf, &nssin, &nssout); 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate (void) freenetconfigent(nconf); 185*132Srobinson if (neterr != ND_OK) 186*132Srobinson return (NULL); 1870Sstevel@tonic-gate return (nssout.nss.host.hent); 1880Sstevel@tonic-gate } 189