1 /* $OpenBSD: getnetnamadr.c,v 1.4 2013/04/04 17:50:19 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 as = getnetbyname_async(name, NULL); 87 if (as == NULL) { 88 h_errno = NETDB_INTERNAL; 89 return (NULL); 90 } 91 92 async_run_sync(as, &ar); 93 94 errno = ar.ar_errno; 95 h_errno = ar.ar_h_errno; 96 if (ar.ar_netent == NULL) 97 return (NULL); 98 99 _fillnetent(ar.ar_netent, &_netent, _entbuf, sizeof(_entbuf)); 100 free(ar.ar_netent); 101 102 return (&_netent); 103 } 104 105 struct netent * 106 getnetbyaddr(in_addr_t net, int type) 107 { 108 struct async *as; 109 struct async_res ar; 110 111 as = getnetbyaddr_async(net, type, NULL); 112 if (as == NULL) { 113 h_errno = NETDB_INTERNAL; 114 return (NULL); 115 } 116 117 async_run_sync(as, &ar); 118 119 errno = ar.ar_errno; 120 h_errno = ar.ar_h_errno; 121 if (ar.ar_netent == NULL) 122 return (NULL); 123 124 _fillnetent(ar.ar_netent, &_netent, _entbuf, sizeof(_entbuf)); 125 free(ar.ar_netent); 126 127 return (&_netent); 128 } 129