1 1.45 nia /* $NetBSD: getnetnamadr.c,v 1.45 2020/06/05 11:16:15 nia Exp $ */ 2 1.2 mrg 3 1.1 mrg /* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro 4 1.1 mrg * Dep. Matematica Universidade de Coimbra, Portugal, Europe 5 1.1 mrg * 6 1.1 mrg * Permission to use, copy, modify, and distribute this software for any 7 1.1 mrg * purpose with or without fee is hereby granted, provided that the above 8 1.1 mrg * copyright notice and this permission notice appear in all copies. 9 1.1 mrg */ 10 1.1 mrg /* 11 1.1 mrg * Copyright (c) 1983, 1993 12 1.1 mrg * The Regents of the University of California. All rights reserved. 13 1.1 mrg * 14 1.1 mrg * Redistribution and use in source and binary forms, with or without 15 1.1 mrg * modification, are permitted provided that the following conditions 16 1.1 mrg * are met: 17 1.1 mrg * 1. Redistributions of source code must retain the above copyright 18 1.1 mrg * notice, this list of conditions and the following disclaimer. 19 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright 20 1.1 mrg * notice, this list of conditions and the following disclaimer in the 21 1.1 mrg * documentation and/or other materials provided with the distribution. 22 1.27 agc * 3. Neither the name of the University nor the names of its contributors 23 1.1 mrg * may be used to endorse or promote products derived from this software 24 1.1 mrg * without specific prior written permission. 25 1.1 mrg * 26 1.1 mrg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 1.1 mrg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 1.1 mrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 1.1 mrg * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 1.1 mrg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 1.1 mrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 1.1 mrg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 1.1 mrg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 1.1 mrg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 1.1 mrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 1.1 mrg * SUCH DAMAGE. 37 1.1 mrg */ 38 1.1 mrg 39 1.2 mrg #include <sys/cdefs.h> 40 1.1 mrg #if defined(LIBC_SCCS) && !defined(lint) 41 1.2 mrg #if 0 42 1.1 mrg static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; 43 1.1 mrg static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; 44 1.5 perry static char rcsid[] = "Id: getnetnamadr.c,v 8.8 1997/06/01 20:34:37 vixie Exp "; 45 1.2 mrg #else 46 1.45 nia __RCSID("$NetBSD: getnetnamadr.c,v 1.45 2020/06/05 11:16:15 nia Exp $"); 47 1.2 mrg #endif 48 1.1 mrg #endif /* LIBC_SCCS and not lint */ 49 1.1 mrg 50 1.3 thorpej #include "namespace.h" 51 1.1 mrg #include <sys/types.h> 52 1.1 mrg #include <sys/param.h> 53 1.1 mrg #include <sys/socket.h> 54 1.1 mrg #include <netinet/in.h> 55 1.1 mrg #include <arpa/inet.h> 56 1.1 mrg #include <arpa/nameser.h> 57 1.1 mrg 58 1.17 lukem #include <assert.h> 59 1.8 lukem #include <ctype.h> 60 1.8 lukem #include <errno.h> 61 1.1 mrg #include <netdb.h> 62 1.8 lukem #include <nsswitch.h> 63 1.1 mrg #include <resolv.h> 64 1.21 wiz #include <stdarg.h> 65 1.8 lukem #include <stdio.h> 66 1.10 lukem #include <stdlib.h> 67 1.1 mrg #include <string.h> 68 1.1 mrg 69 1.10 lukem #ifdef YP 70 1.10 lukem #include <rpc/rpc.h> 71 1.10 lukem #include <rpcsvc/yp_prot.h> 72 1.10 lukem #include <rpcsvc/ypclnt.h> 73 1.10 lukem #endif 74 1.10 lukem 75 1.3 thorpej #ifdef __weak_alias 76 1.19 mycroft __weak_alias(getnetbyaddr,_getnetbyaddr) 77 1.19 mycroft __weak_alias(getnetbyname,_getnetbyname) 78 1.3 thorpej #endif 79 1.3 thorpej 80 1.43 christos #define maybe_ok(res, nm, ok) (((res)->options & RES_NOCHECKNAME) != 0U || \ 81 1.43 christos (ok)(nm) != 0) 82 1.43 christos #define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok) 83 1.43 christos #define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok) 84 1.43 christos 85 1.43 christos 86 1.8 lukem extern int _net_stayopen; 87 1.1 mrg 88 1.1 mrg #define BYADDR 0 89 1.1 mrg #define BYNAME 1 90 1.1 mrg #define MAXALIASES 35 91 1.1 mrg 92 1.24 itojun #define MAXPACKET (64*1024) 93 1.1 mrg 94 1.1 mrg typedef union { 95 1.1 mrg HEADER hdr; 96 1.1 mrg u_char buf[MAXPACKET]; 97 1.1 mrg } querybuf; 98 1.1 mrg 99 1.1 mrg typedef union { 100 1.1 mrg long al; 101 1.1 mrg char ac; 102 1.1 mrg } align; 103 1.1 mrg 104 1.10 lukem #ifdef YP 105 1.10 lukem static char *__ypdomain; 106 1.10 lukem static char *__ypcurrent; 107 1.10 lukem static int __ypcurrentlen; 108 1.10 lukem #endif 109 1.10 lukem 110 1.10 lukem static struct netent net_entry; 111 1.10 lukem static char *net_aliases[MAXALIASES]; 112 1.10 lukem 113 1.40 lukem static int parse_reversed_addr(const char *, in_addr_t *); 114 1.43 christos static struct netent *getnetanswer(res_state, querybuf *, int, int); 115 1.40 lukem static int _files_getnetbyaddr(void *, void *, va_list); 116 1.40 lukem static int _files_getnetbyname(void *, void *, va_list); 117 1.40 lukem static int _dns_getnetbyaddr(void *, void *, va_list); 118 1.40 lukem static int _dns_getnetbyname(void *, void *, va_list); 119 1.10 lukem #ifdef YP 120 1.40 lukem static int _yp_getnetbyaddr(void *, void *, va_list); 121 1.40 lukem static int _yp_getnetbyname(void *, void *, va_list); 122 1.40 lukem static struct netent *_ypnetent(char *); 123 1.10 lukem #endif 124 1.10 lukem 125 1.38 lukem /* 126 1.38 lukem * parse_reversed_addr -- 127 1.38 lukem * parse str, which should be of the form 'd.c.b.a.IN-ADDR.ARPA' 128 1.38 lukem * (a PTR as per RFC 1101) and convert into an in_addr_t of the 129 1.38 lukem * address 'a.b.c.d'. 130 1.38 lukem * returns 0 on success (storing in *result), or -1 on error. 131 1.38 lukem */ 132 1.38 lukem static int 133 1.38 lukem parse_reversed_addr(const char *str, in_addr_t *result) 134 1.38 lukem { 135 1.38 lukem unsigned long octet[4]; 136 1.38 lukem const char *sp; 137 1.38 lukem char *ep; 138 1.38 lukem int octidx; 139 1.38 lukem 140 1.38 lukem sp = str; 141 1.38 lukem /* find the four octets 'd.b.c.a.' */ 142 1.38 lukem for (octidx = 0; octidx < 4; octidx++) { 143 1.38 lukem /* ensure it's a number */ 144 1.38 lukem if (!isdigit((unsigned char)*sp)) 145 1.38 lukem return -1; 146 1.38 lukem octet[octidx] = strtoul(sp, &ep, 10); 147 1.38 lukem /* with a trailing '.' */ 148 1.38 lukem if (*ep != '.') 149 1.38 lukem return -1; 150 1.38 lukem /* and is 0 <= octet <= 255 */ 151 1.38 lukem if (octet[octidx] > 255) 152 1.38 lukem return -1; 153 1.38 lukem sp = ep + 1; 154 1.38 lukem } 155 1.38 lukem /* ensure trailer is correct */ 156 1.38 lukem if (strcasecmp(sp, "IN-ADDR.ARPA") != 0) 157 1.38 lukem return -1; 158 1.38 lukem *result = 0; 159 1.38 lukem /* build result from octets in reverse */ 160 1.38 lukem for (octidx = 3; octidx >= 0; octidx--) { 161 1.38 lukem *result <<= 8; 162 1.42 christos *result |= (in_addr_t)(octet[octidx] & 0xff); 163 1.38 lukem } 164 1.38 lukem return 0; 165 1.38 lukem } 166 1.38 lukem 167 1.1 mrg static struct netent * 168 1.43 christos getnetanswer(res_state res, querybuf *answer, int anslen, int net_i) 169 1.1 mrg { 170 1.40 lukem static char n_name[MAXDNAME]; 171 1.40 lukem static char netbuf[PACKETSZ]; 172 1.40 lukem 173 1.40 lukem HEADER *hp; 174 1.40 lukem u_char *cp; 175 1.40 lukem int n; 176 1.40 lukem u_char *eom; 177 1.40 lukem int type, class, ancount, qdcount, haveanswer; 178 1.40 lukem char *in, *bp, **ap, *ep; 179 1.1 mrg 180 1.17 lukem _DIAGASSERT(answer != NULL); 181 1.43 christos _DIAGASSERT(res != NULL); 182 1.17 lukem 183 1.1 mrg /* 184 1.1 mrg * find first satisfactory answer 185 1.1 mrg * 186 1.1 mrg * answer --> +------------+ ( MESSAGE ) 187 1.1 mrg * | Header | 188 1.1 mrg * +------------+ 189 1.1 mrg * | Question | the question for the name server 190 1.1 mrg * +------------+ 191 1.1 mrg * | Answer | RRs answering the question 192 1.1 mrg * +------------+ 193 1.1 mrg * | Authority | RRs pointing toward an authority 194 1.1 mrg * | Additional | RRs holding additional information 195 1.1 mrg * +------------+ 196 1.1 mrg */ 197 1.1 mrg eom = answer->buf + anslen; 198 1.1 mrg hp = &answer->hdr; 199 1.1 mrg ancount = ntohs(hp->ancount); /* #/records in the answer section */ 200 1.1 mrg qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ 201 1.1 mrg bp = netbuf; 202 1.22 itojun ep = netbuf + sizeof(netbuf); 203 1.1 mrg cp = answer->buf + HFIXEDSZ; 204 1.1 mrg if (!qdcount) { 205 1.1 mrg if (hp->aa) 206 1.1 mrg h_errno = HOST_NOT_FOUND; 207 1.1 mrg else 208 1.1 mrg h_errno = TRY_AGAIN; 209 1.30 christos return NULL; 210 1.1 mrg } 211 1.26 itojun while (qdcount-- > 0) { 212 1.26 itojun n = __dn_skipname(cp, eom); 213 1.26 itojun if (n < 0 || (cp + n + QFIXEDSZ) > eom) { 214 1.26 itojun h_errno = NO_RECOVERY; 215 1.26 itojun return(NULL); 216 1.26 itojun } 217 1.26 itojun cp += n + QFIXEDSZ; 218 1.26 itojun } 219 1.1 mrg ap = net_aliases; 220 1.1 mrg *ap = NULL; 221 1.1 mrg net_entry.n_aliases = net_aliases; 222 1.1 mrg haveanswer = 0; 223 1.39 lukem n_name[0] = '\0'; 224 1.1 mrg while (--ancount >= 0 && cp < eom) { 225 1.42 christos n = dn_expand(answer->buf, eom, cp, bp, (int)(ep - bp)); 226 1.43 christos if ((n < 0) || !maybe_dnok(res, bp)) 227 1.1 mrg break; 228 1.1 mrg cp += n; 229 1.39 lukem (void)strlcpy(n_name, bp, sizeof(n_name)); 230 1.1 mrg GETSHORT(type, cp); 231 1.1 mrg GETSHORT(class, cp); 232 1.1 mrg cp += INT32SZ; /* TTL */ 233 1.1 mrg GETSHORT(n, cp); 234 1.1 mrg if (class == C_IN && type == T_PTR) { 235 1.42 christos n = dn_expand(answer->buf, eom, cp, bp, (int)(ep - bp)); 236 1.43 christos if ((n < 0) || !maybe_hnok(res, bp)) { 237 1.1 mrg cp += n; 238 1.30 christos return NULL; 239 1.1 mrg } 240 1.38 lukem cp += n; 241 1.1 mrg *ap++ = bp; 242 1.1 mrg bp += strlen(bp) + 1; 243 1.1 mrg net_entry.n_addrtype = 244 1.1 mrg (class == C_IN) ? AF_INET : AF_UNSPEC; 245 1.1 mrg haveanswer++; 246 1.1 mrg } 247 1.1 mrg } 248 1.1 mrg if (haveanswer) { 249 1.1 mrg *ap = NULL; 250 1.1 mrg switch (net_i) { 251 1.1 mrg case BYADDR: 252 1.1 mrg net_entry.n_name = *net_entry.n_aliases; 253 1.1 mrg net_entry.n_net = 0L; 254 1.1 mrg break; 255 1.1 mrg case BYNAME: 256 1.26 itojun ap = net_entry.n_aliases; 257 1.26 itojun next_alias: 258 1.26 itojun in = *ap++; 259 1.26 itojun if (in == NULL) { 260 1.26 itojun h_errno = HOST_NOT_FOUND; 261 1.30 christos return NULL; 262 1.26 itojun } 263 1.39 lukem net_entry.n_name = n_name; 264 1.38 lukem if (parse_reversed_addr(in, &net_entry.n_net) == -1) 265 1.32 lukem goto next_alias; 266 1.1 mrg break; 267 1.1 mrg } 268 1.1 mrg net_entry.n_aliases++; 269 1.29 kleink #if (defined(__sparc__) && defined(_LP64)) || \ 270 1.45 nia defined(__alpha__) 271 1.29 kleink net_entry.__n_pad0 = 0; 272 1.29 kleink #endif 273 1.30 christos return &net_entry; 274 1.1 mrg } 275 1.1 mrg h_errno = TRY_AGAIN; 276 1.30 christos return NULL; 277 1.1 mrg } 278 1.1 mrg 279 1.13 christos /*ARGSUSED*/ 280 1.40 lukem static int 281 1.40 lukem _files_getnetbyaddr(void *cbrv, void *cbdata, va_list ap) 282 1.8 lukem { 283 1.40 lukem struct netent **retval = va_arg(ap, struct netent **); 284 1.40 lukem uint32_t net = va_arg(ap, uint32_t); 285 1.40 lukem int type = va_arg(ap, int); 286 1.8 lukem 287 1.40 lukem struct netent *np; 288 1.8 lukem 289 1.8 lukem setnetent(_net_stayopen); 290 1.40 lukem while ((np = getnetent()) != NULL) 291 1.40 lukem if (np->n_addrtype == type && np->n_net == net) 292 1.8 lukem break; 293 1.8 lukem if (!_net_stayopen) 294 1.8 lukem endnetent(); 295 1.40 lukem 296 1.40 lukem if (np != NULL) { 297 1.40 lukem *retval = np; 298 1.40 lukem return NS_SUCCESS; 299 1.40 lukem } else { 300 1.8 lukem h_errno = HOST_NOT_FOUND; 301 1.8 lukem return NS_NOTFOUND; 302 1.8 lukem } 303 1.8 lukem } 304 1.8 lukem 305 1.13 christos /*ARGSUSED*/ 306 1.40 lukem static int 307 1.40 lukem _dns_getnetbyaddr(void *cbrv, void *cbdata, va_list ap) 308 1.1 mrg { 309 1.40 lukem struct netent **retval = va_arg(ap, struct netent **); 310 1.40 lukem uint32_t net = va_arg(ap, uint32_t); 311 1.40 lukem int type = va_arg(ap, int); 312 1.40 lukem 313 1.40 lukem unsigned int netbr[4]; 314 1.40 lukem int nn, anslen; 315 1.40 lukem querybuf *buf; 316 1.40 lukem char qbuf[MAXDNAME]; 317 1.40 lukem uint32_t net2; 318 1.40 lukem struct netent *np; 319 1.40 lukem res_state res; 320 1.8 lukem 321 1.8 lukem if (type != AF_INET) 322 1.8 lukem return NS_UNAVAIL; 323 1.8 lukem 324 1.8 lukem for (nn = 4, net2 = net; net2; net2 >>= 8) 325 1.8 lukem netbr[--nn] = (unsigned int)(net2 & 0xff); 326 1.8 lukem switch (nn) { 327 1.8 lukem default: 328 1.8 lukem return NS_UNAVAIL; 329 1.8 lukem case 3: /* Class A */ 330 1.23 itojun snprintf(qbuf, sizeof(qbuf), "0.0.0.%u.in-addr.arpa", netbr[3]); 331 1.8 lukem break; 332 1.8 lukem case 2: /* Class B */ 333 1.23 itojun snprintf(qbuf, sizeof(qbuf), "0.0.%u.%u.in-addr.arpa", 334 1.23 itojun netbr[3], netbr[2]); 335 1.8 lukem break; 336 1.8 lukem case 1: /* Class C */ 337 1.23 itojun snprintf(qbuf, sizeof(qbuf), "0.%u.%u.%u.in-addr.arpa", 338 1.23 itojun netbr[3], netbr[2], netbr[1]); 339 1.8 lukem break; 340 1.8 lukem case 0: /* Class D - E */ 341 1.23 itojun snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa", 342 1.23 itojun netbr[3], netbr[2], netbr[1], netbr[0]); 343 1.8 lukem break; 344 1.8 lukem } 345 1.24 itojun buf = malloc(sizeof(*buf)); 346 1.24 itojun if (buf == NULL) { 347 1.24 itojun h_errno = NETDB_INTERNAL; 348 1.24 itojun return NS_NOTFOUND; 349 1.24 itojun } 350 1.30 christos res = __res_get_state(); 351 1.41 lukem if (res == NULL) { 352 1.41 lukem free(buf); 353 1.30 christos return NS_NOTFOUND; 354 1.41 lukem } 355 1.42 christos anslen = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, 356 1.42 christos (int)sizeof(buf->buf)); 357 1.8 lukem if (anslen < 0) { 358 1.24 itojun free(buf); 359 1.8 lukem #ifdef DEBUG 360 1.30 christos if (res->options & RES_DEBUG) 361 1.8 lukem printf("res_query failed\n"); 362 1.8 lukem #endif 363 1.30 christos __res_put_state(res); 364 1.8 lukem return NS_NOTFOUND; 365 1.8 lukem } 366 1.44 christos np = getnetanswer(res, buf, anslen, BYADDR); 367 1.30 christos __res_put_state(res); 368 1.24 itojun free(buf); 369 1.10 lukem if (np) { 370 1.8 lukem /* maybe net should be unsigned? */ 371 1.34 tsutsui uint32_t u_net = net; 372 1.8 lukem 373 1.8 lukem /* Strip trailing zeros */ 374 1.8 lukem while ((u_net & 0xff) == 0 && u_net != 0) 375 1.8 lukem u_net >>= 8; 376 1.10 lukem np->n_net = u_net; 377 1.8 lukem } 378 1.40 lukem 379 1.40 lukem if (np != NULL) { 380 1.40 lukem *retval = np; 381 1.40 lukem return NS_SUCCESS; 382 1.40 lukem } else { 383 1.8 lukem h_errno = HOST_NOT_FOUND; 384 1.8 lukem return NS_NOTFOUND; 385 1.8 lukem } 386 1.8 lukem } 387 1.8 lukem 388 1.8 lukem struct netent * 389 1.30 christos getnetbyaddr(uint32_t net, int net_type) 390 1.8 lukem { 391 1.40 lukem int rv; 392 1.40 lukem struct netent *retval; 393 1.40 lukem 394 1.12 lukem static const ns_dtab dtab[] = { 395 1.16 kleink NS_FILES_CB(_files_getnetbyaddr, NULL) 396 1.8 lukem { NSSRC_DNS, _dns_getnetbyaddr, NULL }, /* force -DHESIOD */ 397 1.11 lukem NS_NIS_CB(_yp_getnetbyaddr, NULL) 398 1.35 christos NS_NULL_CB 399 1.8 lukem }; 400 1.1 mrg 401 1.40 lukem retval = NULL; 402 1.10 lukem h_errno = NETDB_INTERNAL; 403 1.40 lukem rv = nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyaddr", 404 1.40 lukem __nsdefaultsrc, &retval, net, net_type); 405 1.40 lukem if (rv == NS_SUCCESS) { 406 1.40 lukem h_errno = NETDB_SUCCESS; 407 1.40 lukem return retval; 408 1.40 lukem } 409 1.40 lukem return NULL; 410 1.8 lukem } 411 1.3 thorpej 412 1.13 christos /*ARGSUSED*/ 413 1.40 lukem static int 414 1.40 lukem _files_getnetbyname(void *cbrv, void *cbdata, va_list ap) 415 1.8 lukem { 416 1.40 lukem struct netent **retval = va_arg(ap, struct netent **); 417 1.40 lukem const char *name = va_arg(ap, const char *); 418 1.8 lukem 419 1.40 lukem struct netent *np; 420 1.40 lukem char **cp; 421 1.17 lukem 422 1.8 lukem setnetent(_net_stayopen); 423 1.40 lukem while ((np = getnetent()) != NULL) { 424 1.40 lukem if (strcasecmp(np->n_name, name) == 0) 425 1.8 lukem break; 426 1.40 lukem for (cp = np->n_aliases; *cp != 0; cp++) 427 1.8 lukem if (strcasecmp(*cp, name) == 0) 428 1.8 lukem goto found; 429 1.8 lukem } 430 1.8 lukem found: 431 1.8 lukem if (!_net_stayopen) 432 1.8 lukem endnetent(); 433 1.40 lukem 434 1.40 lukem if (np != NULL) { 435 1.40 lukem *retval = np; 436 1.40 lukem return NS_SUCCESS; 437 1.40 lukem } else { 438 1.8 lukem h_errno = HOST_NOT_FOUND; 439 1.8 lukem return NS_NOTFOUND; 440 1.8 lukem } 441 1.8 lukem } 442 1.8 lukem 443 1.13 christos /*ARGSUSED*/ 444 1.40 lukem static int 445 1.40 lukem _dns_getnetbyname(void *cbrv, void *cbdata, va_list ap) 446 1.8 lukem { 447 1.40 lukem struct netent **retval = va_arg(ap, struct netent **); 448 1.40 lukem const char *name = va_arg(ap, const char *); 449 1.8 lukem 450 1.40 lukem int anslen; 451 1.40 lukem querybuf *buf; 452 1.40 lukem char qbuf[MAXDNAME]; 453 1.40 lukem struct netent *np; 454 1.40 lukem res_state res; 455 1.17 lukem 456 1.40 lukem strlcpy(&qbuf[0], name, sizeof(qbuf)); 457 1.24 itojun buf = malloc(sizeof(*buf)); 458 1.24 itojun if (buf == NULL) { 459 1.24 itojun h_errno = NETDB_INTERNAL; 460 1.24 itojun return NS_NOTFOUND; 461 1.24 itojun } 462 1.30 christos res = __res_get_state(); 463 1.33 ginsbach if (res == NULL) { 464 1.33 ginsbach free(buf); 465 1.30 christos return NS_NOTFOUND; 466 1.33 ginsbach } 467 1.30 christos anslen = res_nsearch(res, qbuf, C_IN, T_PTR, buf->buf, 468 1.42 christos (int)sizeof(buf->buf)); 469 1.8 lukem if (anslen < 0) { 470 1.24 itojun free(buf); 471 1.1 mrg #ifdef DEBUG 472 1.30 christos if (res->options & RES_DEBUG) 473 1.24 itojun printf("res_search failed\n"); 474 1.1 mrg #endif 475 1.30 christos __res_put_state(res); 476 1.8 lukem return NS_NOTFOUND; 477 1.8 lukem } 478 1.44 christos np = getnetanswer(res, buf, anslen, BYNAME); 479 1.30 christos __res_put_state(res); 480 1.24 itojun free(buf); 481 1.40 lukem 482 1.40 lukem if (np != NULL) { 483 1.40 lukem *retval = np; 484 1.40 lukem return NS_SUCCESS; 485 1.40 lukem } else { 486 1.8 lukem h_errno = HOST_NOT_FOUND; 487 1.8 lukem return NS_NOTFOUND; 488 1.1 mrg } 489 1.1 mrg } 490 1.1 mrg 491 1.1 mrg struct netent * 492 1.40 lukem getnetbyname(const char *name) 493 1.1 mrg { 494 1.40 lukem int rv; 495 1.40 lukem struct netent *retval; 496 1.40 lukem 497 1.12 lukem static const ns_dtab dtab[] = { 498 1.16 kleink NS_FILES_CB(_files_getnetbyname, NULL) 499 1.8 lukem { NSSRC_DNS, _dns_getnetbyname, NULL }, /* force -DHESIOD */ 500 1.11 lukem NS_NIS_CB(_yp_getnetbyname, NULL) 501 1.35 christos NS_NULL_CB 502 1.8 lukem }; 503 1.1 mrg 504 1.40 lukem _DIAGASSERT(name != NULL); 505 1.17 lukem 506 1.40 lukem retval = NULL; 507 1.10 lukem h_errno = NETDB_INTERNAL; 508 1.40 lukem rv = nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyname", 509 1.40 lukem __nsdefaultsrc, &retval, name); 510 1.40 lukem if (rv == NS_SUCCESS) { 511 1.40 lukem h_errno = NETDB_SUCCESS; 512 1.40 lukem return retval; 513 1.40 lukem } 514 1.40 lukem return NULL; 515 1.10 lukem } 516 1.10 lukem 517 1.10 lukem #ifdef YP 518 1.15 christos /*ARGSUSED*/ 519 1.40 lukem static int 520 1.40 lukem _yp_getnetbyaddr(void *cbrv, void *cb_data, va_list ap) 521 1.10 lukem { 522 1.40 lukem struct netent **retval = va_arg(ap, struct netent **); 523 1.40 lukem uint32_t net = va_arg(ap, uint32_t); 524 1.40 lukem int type = va_arg(ap, int); 525 1.40 lukem 526 1.40 lukem struct netent *np; 527 1.40 lukem char qbuf[MAXDNAME]; 528 1.40 lukem unsigned int netbr[4]; 529 1.40 lukem uint32_t net2; 530 1.40 lukem int r; 531 1.10 lukem 532 1.10 lukem if (type != AF_INET) 533 1.10 lukem return NS_UNAVAIL; 534 1.10 lukem 535 1.10 lukem if (!__ypdomain) { 536 1.10 lukem if (_yp_check(&__ypdomain) == 0) 537 1.10 lukem return NS_UNAVAIL; 538 1.10 lukem } 539 1.10 lukem np = NULL; 540 1.10 lukem if (__ypcurrent) 541 1.10 lukem free(__ypcurrent); 542 1.10 lukem __ypcurrent = NULL; 543 1.10 lukem for (r = 4, net2 = net; net2; net2 >>= 8) 544 1.10 lukem netbr[--r] = (unsigned int)(net2 & 0xff); 545 1.10 lukem switch (r) { 546 1.10 lukem default: 547 1.10 lukem return NS_UNAVAIL; 548 1.10 lukem case 3: /* Class A */ 549 1.28 lukem snprintf(qbuf, sizeof(qbuf), "%u", netbr[3]); 550 1.10 lukem break; 551 1.10 lukem case 2: /* Class B */ 552 1.28 lukem snprintf(qbuf, sizeof(qbuf), "%u.%u", netbr[2], netbr[3]); 553 1.10 lukem break; 554 1.10 lukem case 1: /* Class C */ 555 1.28 lukem snprintf(qbuf, sizeof(qbuf), "%u.%u.%u", netbr[1], netbr[2], 556 1.28 lukem netbr[3]); 557 1.10 lukem break; 558 1.10 lukem case 0: /* Class D - E */ 559 1.23 itojun snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u", netbr[0], netbr[1], 560 1.23 itojun netbr[2], netbr[3]); 561 1.10 lukem break; 562 1.10 lukem } 563 1.10 lukem r = yp_match(__ypdomain, "networks.byaddr", qbuf, (int)strlen(qbuf), 564 1.10 lukem &__ypcurrent, &__ypcurrentlen); 565 1.10 lukem if (r == 0) 566 1.10 lukem np = _ypnetent(__ypcurrent); 567 1.10 lukem 568 1.40 lukem if (np != NULL) { 569 1.40 lukem *retval = np; 570 1.40 lukem return NS_SUCCESS; 571 1.40 lukem } else { 572 1.10 lukem h_errno = HOST_NOT_FOUND; 573 1.10 lukem return NS_NOTFOUND; 574 1.10 lukem } 575 1.10 lukem } 576 1.10 lukem 577 1.15 christos /*ARGSUSED*/ 578 1.40 lukem static int 579 1.40 lukem _yp_getnetbyname(void *cbrv, void *cbdata, va_list ap) 580 1.10 lukem { 581 1.40 lukem struct netent **retval = va_arg(ap, struct netent **); 582 1.40 lukem const char *name = va_arg(ap, const char *); 583 1.10 lukem 584 1.40 lukem struct netent *np; 585 1.40 lukem int r; 586 1.10 lukem 587 1.10 lukem if (!__ypdomain) { 588 1.10 lukem if (_yp_check(&__ypdomain) == 0) 589 1.10 lukem return NS_UNAVAIL; 590 1.10 lukem } 591 1.10 lukem np = NULL; 592 1.10 lukem if (__ypcurrent) 593 1.10 lukem free(__ypcurrent); 594 1.10 lukem __ypcurrent = NULL; 595 1.10 lukem r = yp_match(__ypdomain, "networks.byname", name, (int)strlen(name), 596 1.10 lukem &__ypcurrent, &__ypcurrentlen); 597 1.10 lukem if (r == 0) 598 1.10 lukem np = _ypnetent(__ypcurrent); 599 1.10 lukem 600 1.40 lukem if (np != NULL) { 601 1.40 lukem *retval = np; 602 1.40 lukem return NS_SUCCESS; 603 1.40 lukem } else { 604 1.10 lukem h_errno = HOST_NOT_FOUND; 605 1.10 lukem return NS_NOTFOUND; 606 1.10 lukem } 607 1.10 lukem } 608 1.10 lukem 609 1.40 lukem static struct netent * 610 1.30 christos _ypnetent(char *line) 611 1.10 lukem { 612 1.10 lukem char *cp, *p, **q; 613 1.17 lukem 614 1.17 lukem _DIAGASSERT(line != NULL); 615 1.10 lukem 616 1.10 lukem net_entry.n_name = line; 617 1.10 lukem cp = strpbrk(line, " \t"); 618 1.10 lukem if (cp == NULL) 619 1.30 christos return NULL; 620 1.10 lukem *cp++ = '\0'; 621 1.10 lukem while (*cp == ' ' || *cp == '\t') 622 1.10 lukem cp++; 623 1.10 lukem p = strpbrk(cp, " \t"); 624 1.10 lukem if (p != NULL) 625 1.10 lukem *p++ = '\0'; 626 1.10 lukem net_entry.n_net = inet_network(cp); 627 1.29 kleink #if (defined(__sparc__) && defined(_LP64)) || \ 628 1.45 nia defined(__alpha__) 629 1.29 kleink net_entry.__n_pad0 = 0; 630 1.29 kleink #endif 631 1.10 lukem net_entry.n_addrtype = AF_INET; 632 1.10 lukem q = net_entry.n_aliases = net_aliases; 633 1.10 lukem if (p != NULL) { 634 1.10 lukem cp = p; 635 1.10 lukem while (cp && *cp) { 636 1.10 lukem if (*cp == ' ' || *cp == '\t') { 637 1.10 lukem cp++; 638 1.10 lukem continue; 639 1.10 lukem } 640 1.10 lukem if (q < &net_aliases[MAXALIASES - 1]) 641 1.10 lukem *q++ = cp; 642 1.10 lukem cp = strpbrk(cp, " \t"); 643 1.10 lukem if (cp != NULL) 644 1.10 lukem *cp++ = '\0'; 645 1.10 lukem } 646 1.1 mrg } 647 1.10 lukem *q = NULL; 648 1.10 lukem 649 1.30 christos return &net_entry; 650 1.1 mrg } 651 1.10 lukem #endif 652