1 /* $OpenBSD: getnetnamadr.c,v 1.8 2014/03/26 18:13:15 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 <sys/socket.h> 20 #include <netinet/in.h> 21 #include <netdb.h> 22 23 #include <asr.h> 24 #include <errno.h> 25 #include <resolv.h> 26 #include <stdlib.h> 27 #include <string.h> 28 29 static void _fillnetent(const struct netent *, struct netent *, char *buf, 30 size_t); 31 32 static struct netent _netent; 33 static char _entbuf[4096]; 34 35 static char *_empty[] = { NULL, }; 36 37 static void 38 _fillnetent(const struct netent *e, struct netent *r, char *buf, size_t len) 39 { 40 char **ptr, *end, *pos; 41 size_t n, i; 42 int naliases; 43 44 bzero(buf, len); 45 bzero(r, sizeof(*r)); 46 r->n_aliases = _empty; 47 48 end = buf + len; 49 ptr = (char **)ALIGN(buf); 50 51 if ((char *)ptr >= end) 52 return; 53 54 for (naliases = 0; e->n_aliases[naliases]; naliases++) 55 ; 56 57 r->n_name = NULL; 58 r->n_addrtype = e->n_addrtype; 59 r->n_net = e->n_net; 60 r->n_aliases = ptr; 61 62 pos = (char *)(ptr + (naliases + 1)); 63 if (pos > end) 64 r->n_aliases = _empty; 65 66 n = strlcpy(pos, e->n_name, end - pos); 67 if (n >= end - pos) 68 return; 69 r->n_name = pos; 70 pos += n + 1; 71 72 for (i = 0; i < naliases; i++) { 73 n = strlcpy(pos, e->n_aliases[i], end - pos); 74 if (n >= end - pos) 75 return; 76 r->n_aliases[i] = pos; 77 pos += n + 1; 78 } 79 } 80 81 struct netent * 82 getnetbyname(const char *name) 83 { 84 struct asr_query *as; 85 struct asr_result ar; 86 87 res_init(); 88 89 as = getnetbyname_async(name, NULL); 90 if (as == NULL) { 91 h_errno = NETDB_INTERNAL; 92 return (NULL); 93 } 94 95 asr_run_sync(as, &ar); 96 97 errno = ar.ar_errno; 98 h_errno = ar.ar_h_errno; 99 if (ar.ar_netent == NULL) 100 return (NULL); 101 102 _fillnetent(ar.ar_netent, &_netent, _entbuf, sizeof(_entbuf)); 103 free(ar.ar_netent); 104 105 return (&_netent); 106 } 107 108 struct netent * 109 getnetbyaddr(in_addr_t net, int type) 110 { 111 struct asr_query *as; 112 struct asr_result ar; 113 114 res_init(); 115 116 as = getnetbyaddr_async(net, type, NULL); 117 if (as == NULL) { 118 h_errno = NETDB_INTERNAL; 119 return (NULL); 120 } 121 122 asr_run_sync(as, &ar); 123 124 errno = ar.ar_errno; 125 h_errno = ar.ar_h_errno; 126 if (ar.ar_netent == NULL) 127 return (NULL); 128 129 _fillnetent(ar.ar_netent, &_netent, _entbuf, sizeof(_entbuf)); 130 free(ar.ar_netent); 131 132 return (&_netent); 133 } 134