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