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 2006 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 * gethostbyname_r() is defined in this file. It is implemented on top of 32 * _get_hostserv_inetnetdir_byname() which is also used to implement 33 * netdir_getbyname() for inet family transports. In turn the common code 34 * uses the name service switch policy for "hosts" and "services" unless 35 * the administrator chooses to bypass the name service switch by 36 * specifying third-party supplied nametoaddr libs for inet transports 37 * in /etc/netconfig. 38 * 39 * gethostbyaddr_r() is similarly related to _get_hostserv_inetnetdir_byaddr() 40 * and netdir_getbyaddr(); 41 * 42 * The common code lives in netdir_inet.c. 43 * 44 * gethostent_r(), sethostent() and endhostent() are *not* implemented on top 45 * of the common interface; they go straight to the switch and are 46 * defined in gethostent_r.c. 47 * 48 * There is absolutely no data sharing, not even the stayopen flag or 49 * enumeration state, between gethostbyYY_r() and gethostent_r(); 50 */ 51 52 #include "mt.h" 53 #include <netdb.h> 54 #include <netdir.h> 55 #include <sys/types.h> 56 #include <nss_netdir.h> 57 #include <string.h> 58 59 extern struct netconfig *__rpc_getconfip(); 60 61 /* 62 * h_errno POLICY: The frontends expect the name service 63 * backends to modify the h_errno in "arg"; _switch_gethostbyYY_r() 64 * will copy that over onto user's h_errnop pointer. This h_errno is 65 * never used for "switching" -- status from nss_search serves 66 * the purpose. There is no explicit zeroing in the case of success. 67 */ 68 69 extern struct hostent * 70 _switch_gethostbyname_r(const char *nam, struct hostent *result, char *buffer, 71 int buflen, int *h_errnop); 72 73 extern struct hostent * 74 _switch_gethostbyaddr_r(const char *addr, int length, int type, 75 struct hostent *result, char *buffer, int buflen, int *h_errnop); 76 77 #ifdef PIC 78 struct hostent * 79 _uncached_gethostbyname_r(const char *nam, struct hostent *result, 80 char *buffer, int buflen, int *h_errnop) 81 { 82 return (_switch_gethostbyname_r(nam, result, 83 buffer, buflen, h_errnop)); 84 } 85 86 struct hostent * 87 _uncached_gethostbyaddr_r(const char *addr, int length, int type, 88 struct hostent *result, char *buffer, int buflen, int *h_errnop) 89 { 90 return (_switch_gethostbyaddr_r(addr, length, type, 91 result, buffer, buflen, h_errnop)); 92 } 93 94 #endif 95 96 extern struct hostent * 97 gethostbyname_r(const char *nam, struct hostent *result, char *buffer, 98 int buflen, int *h_errnop); 99 100 extern struct hostent * 101 gethostbyaddr_r(const char *addr, int length, int type, 102 struct hostent *result, char *buffer, int buflen, int *h_errnop); 103 104 struct hostent * 105 gethostbyname_r(const char *nam, struct hostent *result, char *buffer, 106 int buflen, int *h_errnop) 107 { 108 struct netconfig *nconf; 109 struct nss_netdirbyname_in nssin; 110 union nss_netdirbyname_out nssout; 111 int neterr, dummy; 112 113 if (h_errnop == NULL) 114 h_errnop = &dummy; 115 116 if (strlen(nam) == 0) { 117 *h_errnop = HOST_NOT_FOUND; 118 return (NULL); 119 } 120 121 if ((nconf = __rpc_getconfip("udp")) == NULL && 122 (nconf = __rpc_getconfip("tcp")) == NULL) { 123 *h_errnop = NO_RECOVERY; 124 return (NULL); 125 } 126 127 nssin.op_t = NSS_HOST; 128 nssin.arg.nss.host.name = nam; 129 nssin.arg.nss.host.buf = buffer; 130 nssin.arg.nss.host.buflen = buflen; 131 132 nssout.nss.host.hent = result; 133 nssout.nss.host.herrno_p = h_errnop; 134 135 /* 136 * We pass in nconf and let the implementation of the long-named func 137 * decide whether to use the switch based on nc_nlookups. 138 */ 139 neterr = _get_hostserv_inetnetdir_byname(nconf, &nssin, &nssout); 140 141 (void) freenetconfigent(nconf); 142 if (neterr != ND_OK) 143 return (NULL); 144 return (nssout.nss.host.hent); 145 } 146 147 struct hostent * 148 gethostbyaddr_r(const char *addr, int length, int type, 149 struct hostent *result, char *buffer, int buflen, int *h_errnop) 150 { 151 struct netconfig *nconf; 152 struct nss_netdirbyaddr_in nssin; 153 union nss_netdirbyaddr_out nssout; 154 int neterr; 155 156 if (type != AF_INET) { 157 *h_errnop = HOST_NOT_FOUND; 158 return (NULL); 159 } 160 161 if ((nconf = __rpc_getconfip("udp")) == NULL && 162 (nconf = __rpc_getconfip("tcp")) == NULL) { 163 *h_errnop = NO_RECOVERY; 164 return (NULL); 165 } 166 167 nssin.op_t = NSS_HOST; 168 nssin.arg.nss.host.addr = addr; 169 nssin.arg.nss.host.len = length; 170 nssin.arg.nss.host.type = type; 171 nssin.arg.nss.host.buf = buffer; 172 nssin.arg.nss.host.buflen = buflen; 173 174 nssout.nss.host.hent = result; 175 nssout.nss.host.herrno_p = h_errnop; 176 177 /* 178 * We pass in nconf and let the implementation of this long-named func 179 * decide whether to use the switch based on nc_nlookups. 180 */ 181 neterr = _get_hostserv_inetnetdir_byaddr(nconf, &nssin, &nssout); 182 183 (void) freenetconfigent(nconf); 184 if (neterr != ND_OK) 185 return (NULL); 186 return (nssout.nss.host.hent); 187 } 188