1 /* $OpenBSD: getnetnamadr.c,v 1.5 2013/05/27 17:31:01 eric Exp $ */ 2 /* 3 * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/types.h> 19 #include <netinet/in.h> 20 21 #include <errno.h> 22 #include <resolv.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #include "asr.h" 27 28 static void _fillnetent(const struct netent *, struct netent *, char *buf, 29 size_t); 30 31 static struct netent _netent; 32 static char _entbuf[4096]; 33 34 static char *_empty[] = { NULL, }; 35 36 static void 37 _fillnetent(const struct netent *e, struct netent *r, char *buf, size_t len) 38 { 39 char **ptr, *end, *pos; 40 size_t n, i; 41 int naliases; 42 43 bzero(buf, len); 44 bzero(r, sizeof(*r)); 45 r->n_aliases = _empty; 46 47 end = buf + len; 48 ptr = (char **)ALIGN(buf); 49 50 if ((char *)ptr >= end) 51 return; 52 53 for (naliases = 0; e->n_aliases[naliases]; naliases++) 54 ; 55 56 r->n_name = NULL; 57 r->n_addrtype = e->n_addrtype; 58 r->n_net = e->n_net; 59 r->n_aliases = ptr; 60 61 pos = (char *)(ptr + (naliases + 1)); 62 if (pos > end) 63 r->n_aliases = _empty; 64 65 n = strlcpy(pos, e->n_name, end - pos); 66 if (n >= end - pos) 67 return; 68 r->n_name = pos; 69 pos += n + 1; 70 71 for (i = 0; i < naliases; i++) { 72 n = strlcpy(pos, e->n_aliases[i], end - pos); 73 if (n >= end - pos) 74 return; 75 r->n_aliases[i] = pos; 76 pos += n + 1; 77 } 78 } 79 80 struct netent * 81 getnetbyname(const char *name) 82 { 83 struct async *as; 84 struct async_res ar; 85 86 res_init(); 87 88 as = getnetbyname_async(name, NULL); 89 if (as == NULL) { 90 h_errno = NETDB_INTERNAL; 91 return (NULL); 92 } 93 94 async_run_sync(as, &ar); 95 96 errno = ar.ar_errno; 97 h_errno = ar.ar_h_errno; 98 if (ar.ar_netent == NULL) 99 return (NULL); 100 101 _fillnetent(ar.ar_netent, &_netent, _entbuf, sizeof(_entbuf)); 102 free(ar.ar_netent); 103 104 return (&_netent); 105 } 106 107 struct netent * 108 getnetbyaddr(in_addr_t net, int type) 109 { 110 struct async *as; 111 struct async_res ar; 112 113 res_init(); 114 115 as = getnetbyaddr_async(net, type, NULL); 116 if (as == NULL) { 117 h_errno = NETDB_INTERNAL; 118 return (NULL); 119 } 120 121 async_run_sync(as, &ar); 122 123 errno = ar.ar_errno; 124 h_errno = ar.ar_h_errno; 125 if (ar.ar_netent == NULL) 126 return (NULL); 127 128 _fillnetent(ar.ar_netent, &_netent, _entbuf, sizeof(_entbuf)); 129 free(ar.ar_netent); 130 131 return (&_netent); 132 } 133