1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 /* 31 * lib/libnsl/nss/gethostbyname_r.c 32 * 33 * gethostbyname_r() is defined in this file. It is implemented on top of 34 * _get_hostserv_inetnetdir_byname() which is also used to implement 35 * netdir_getbyname() for inet family transports. In turn the common code 36 * uses the name service switch policy for "hosts" and "services" unless 37 * the administrator chooses to bypass the name service switch by 38 * specifying third-party supplied nametoaddr libs for inet transports 39 * in /etc/netconfig. 40 * 41 * gethostbyaddr_r() is similarly related to _get_hostserv_inetnetdir_byaddr() 42 * and netdir_getbyaddr(); 43 * 44 * The common code lives in netdir_inet.c. 45 * 46 * gethostent_r(), sethostent() and endhostent() are *not* implemented on top 47 * of the common interface; they go straight to the switch and are 48 * defined in gethostent_r.c. 49 * 50 * There is absolutely no data sharing, not even the stayopen flag or 51 * enumeration state, between gethostbyYY_r() and gethostent_r(); 52 */ 53 54 #include <netdb.h> 55 #include <netdir.h> 56 #include <sys/types.h> 57 #include <nss_netdir.h> 58 #include <string.h> 59 60 extern struct netconfig *__rpc_getconfip(); 61 62 /* 63 * h_errno POLICY: The frontends expect the name service 64 * backends to modify the h_errno in "arg"; _switch_gethostbyYY_r() 65 * will copy that over onto user's h_errnop pointer. This h_errno is 66 * never used for "switching" -- status from nss_search serves 67 * the purpose. There is no explicit zeroing in the case of success. 68 */ 69 70 extern struct hostent * 71 _switch_gethostbyname_r(const char *nam, struct hostent *result, char *buffer, 72 int buflen, int *h_errnop); 73 74 extern struct hostent * 75 _switch_gethostbyaddr_r(const char *addr, int length, int type, 76 struct hostent *result, char *buffer, int buflen, int *h_errnop); 77 78 #ifdef PIC 79 struct hostent * 80 _uncached_gethostbyname_r(const char *nam, struct hostent *result, 81 char *buffer, int buflen, int *h_errnop) 82 { 83 return (_switch_gethostbyname_r(nam, result, 84 buffer, buflen, h_errnop)); 85 } 86 87 struct hostent * 88 _uncached_gethostbyaddr_r(const char *addr, int length, int type, 89 struct hostent *result, char *buffer, int buflen, int *h_errnop) 90 { 91 return (_switch_gethostbyaddr_r(addr, length, type, 92 result, buffer, buflen, h_errnop)); 93 } 94 95 #endif 96 97 extern struct hostent * 98 gethostbyname_r(const char *nam, struct hostent *result, char *buffer, 99 int buflen, int *h_errnop); 100 101 extern struct hostent * 102 gethostbyaddr_r(const char *addr, int length, int type, 103 struct hostent *result, char *buffer, int buflen, int *h_errnop); 104 105 struct hostent * 106 gethostbyname_r(const char *nam, struct hostent *result, char *buffer, 107 int buflen, int *h_errnop) 108 { 109 struct netconfig *nconf; 110 struct nss_netdirbyname_in nssin; 111 union nss_netdirbyname_out nssout; 112 int neterr, dummy; 113 114 if (h_errnop == NULL) 115 h_errnop = &dummy; 116 117 if (strlen(nam) == 0) { 118 *h_errnop = HOST_NOT_FOUND; 119 return (NULL); 120 } 121 122 if ((nconf = __rpc_getconfip("udp")) == NULL && 123 (nconf = __rpc_getconfip("tcp")) == NULL) { 124 *h_errnop = NO_RECOVERY; 125 return (NULL); 126 } 127 128 nssin.op_t = NSS_HOST; 129 nssin.arg.nss.host.name = nam; 130 nssin.arg.nss.host.buf = buffer; 131 nssin.arg.nss.host.buflen = buflen; 132 133 nssout.nss.host.hent = result; 134 nssout.nss.host.herrno_p = h_errnop; 135 136 /* 137 * We pass in nconf and let the implementation of the long-named func 138 * decide whether to use the switch based on nc_nlookups. 139 */ 140 neterr = _get_hostserv_inetnetdir_byname(nconf, &nssin, &nssout); 141 142 (void) freenetconfigent(nconf); 143 if (neterr != ND_OK) 144 return (NULL); 145 return (nssout.nss.host.hent); 146 } 147 148 struct hostent * 149 gethostbyaddr_r(const char *addr, int length, int type, 150 struct hostent *result, char *buffer, int buflen, int *h_errnop) 151 { 152 struct netconfig *nconf; 153 struct nss_netdirbyaddr_in nssin; 154 union nss_netdirbyaddr_out nssout; 155 int neterr; 156 157 if (type != AF_INET) { 158 *h_errnop = HOST_NOT_FOUND; 159 return (NULL); 160 } 161 162 if ((nconf = __rpc_getconfip("udp")) == NULL && 163 (nconf = __rpc_getconfip("tcp")) == NULL) { 164 *h_errnop = NO_RECOVERY; 165 return (NULL); 166 } 167 168 nssin.op_t = NSS_HOST; 169 nssin.arg.nss.host.addr = addr; 170 nssin.arg.nss.host.len = length; 171 nssin.arg.nss.host.type = type; 172 nssin.arg.nss.host.buf = buffer; 173 nssin.arg.nss.host.buflen = buflen; 174 175 nssout.nss.host.hent = result; 176 nssout.nss.host.herrno_p = h_errnop; 177 178 /* 179 * We pass in nconf and let the implementation of this long-named func 180 * decide whether to use the switch based on nc_nlookups. 181 */ 182 neterr = _get_hostserv_inetnetdir_byaddr(nconf, &nssin, &nssout); 183 184 (void) freenetconfigent(nconf); 185 if (neterr != ND_OK) 186 return (NULL); 187 return (nssout.nss.host.hent); 188 } 189