getnetnamadr.c revision 146244
1/*- 2 * Copyright (c) 1994, Garrett Wollman 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> 27__FBSDID("$FreeBSD: head/lib/libc/net/getnetnamadr.c 146244 2005-05-15 20:15:15Z ume $"); 28 29#include "namespace.h" 30#include "reentrant.h" 31#include <sys/param.h> 32#include <sys/socket.h> 33#include <netinet/in.h> 34#include <arpa/inet.h> 35#include <netdb.h> 36#include <stdio.h> 37#include <ctype.h> 38#include <stdlib.h> 39#include <string.h> 40#include <stdarg.h> 41#include <nsswitch.h> 42#include "un-namespace.h" 43#include "netdb_private.h" 44 45extern int _ht_getnetbyname(void *, void *, va_list); 46extern int _dns_getnetbyname(void *, void *, va_list); 47extern int _nis_getnetbyname(void *, void *, va_list); 48extern int _ht_getnetbyaddr(void *, void *, va_list); 49extern int _dns_getnetbyaddr(void *, void *, va_list); 50extern int _nis_getnetbyaddr(void *, void *, va_list); 51 52/* Network lookup order if nsswitch.conf is broken or nonexistant */ 53static const ns_src default_src[] = { 54 { NSSRC_FILES, NS_SUCCESS }, 55 { NSSRC_DNS, NS_SUCCESS }, 56 { 0 } 57}; 58 59static struct netdata netdata; 60static thread_key_t netdata_key; 61static once_t netdata_init_once = ONCE_INITIALIZER; 62static int netdata_thr_keycreated = 0; 63 64static void 65netdata_free(void *ptr) 66{ 67 struct netdata *nd = ptr; 68 69 if (nd == NULL) 70 return; 71 nd->data.stayopen = 0; 72 _endnethtent(&nd->data); 73 free(nd); 74} 75 76static void 77netdata_keycreate(void) 78{ 79 netdata_thr_keycreated = 80 (thr_keycreate(&netdata_key, netdata_free) == 0); 81} 82 83struct netdata * 84__netdata_init(void) 85{ 86 struct netdata *nd; 87 88 if (thr_main() != 0) 89 return &netdata; 90 if (thr_once(&netdata_init_once, netdata_keycreate) != 0 || 91 !netdata_thr_keycreated) 92 return NULL; 93 if ((nd = thr_getspecific(netdata_key)) != NULL) 94 return nd; 95 if ((nd = calloc(1, sizeof(*nd))) == NULL) 96 return NULL; 97 if (thr_setspecific(netdata_key, nd) == 0) 98 return nd; 99 free(nd); 100 return NULL; 101} 102 103int 104getnetbyname_r(const char *name, struct netent *ne, struct netent_data *ned) 105{ 106 int rval; 107 108 109 static const ns_dtab dtab[] = { 110 NS_FILES_CB(_ht_getnetbyname, NULL) 111 { NSSRC_DNS, _dns_getnetbyname, NULL }, 112 NS_NIS_CB(_nis_getnetbyname, NULL) /* force -DHESIOD */ 113 { 0 } 114 }; 115 116 rval = _nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyname", 117 default_src, name, ne, ned); 118 119 return (rval == NS_SUCCESS) ? 0 : -1; 120} 121 122int 123getnetbyaddr_r(uint32_t addr, int af, struct netent *ne, 124 struct netent_data *ned) 125{ 126 int rval; 127 128 static const ns_dtab dtab[] = { 129 NS_FILES_CB(_ht_getnetbyaddr, NULL) 130 { NSSRC_DNS, _dns_getnetbyaddr, NULL }, 131 NS_NIS_CB(_nis_getnetbyaddr, NULL) /* force -DHESIOD */ 132 { 0 } 133 }; 134 135 rval = _nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyaddr", 136 default_src, addr, af, ne, ned); 137 138 return (rval == NS_SUCCESS) ? 0 : -1; 139} 140 141void 142setnetent_r(int stayopen, struct netent_data *ned) 143{ 144 _setnethtent(stayopen, ned); 145 _setnetdnsent(stayopen); 146} 147 148void 149endnetent_r(struct netent_data *ned) 150{ 151 _endnethtent(ned); 152 _endnetdnsent(); 153} 154 155struct netent * 156getnetbyname(const char *name) 157{ 158 struct netdata *nd; 159 160 if ((nd = __netdata_init()) == NULL) 161 return NULL; 162 if (getnetbyname_r(name, &nd->net, &nd->data) != 0) 163 return NULL; 164 return &nd->net; 165} 166 167struct netent * 168#if __LONG_BIT == 64 169getnetbyaddr(u_long addr, int af) /* ABI compatibility */ 170#else 171getnetbyaddr(uint32_t addr, int af) 172#endif 173{ 174 struct netdata *nd; 175 176 if ((nd = __netdata_init()) == NULL) 177 return NULL; 178 if (getnetbyaddr_r((uint32_t)addr, af, &nd->net, &nd->data) != 0) 179 return NULL; 180 return &nd->net; 181} 182 183void 184setnetent(int stayopen) 185{ 186 struct netdata *nd; 187 188 if ((nd = __netdata_init()) == NULL) 189 return; 190 setnetent_r(stayopen, &nd->data); 191} 192 193void 194endnetent(void) 195{ 196 struct netdata *nd; 197 198 if ((nd = __netdata_init()) == NULL) 199 return; 200 endnetent_r(&nd->data); 201} 202