1 /* $OpenBSD: getnetnamadr.c,v 1.1 2012/09/08 11:08:21 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 end = buf + len; 44 ptr = (char**)buf; /* XXX align */ 45 46 for (naliases = 0; e->n_aliases[naliases]; naliases++) 47 ; 48 49 r->n_name = NULL; 50 r->n_addrtype = e->n_addrtype; 51 r->n_net = e->n_net; 52 r->n_aliases = ptr; 53 54 pos = (char *)(ptr + (naliases + 1)); 55 if (pos > end) { 56 r->n_aliases = _empty; 57 return; 58 } 59 bzero(ptr, pos - (char *)ptr); 60 61 n = strlcpy(pos, e->n_name, end - pos); 62 if (n >= end - pos) 63 return; 64 r->n_name = pos; 65 pos += n + 1; 66 67 for(i = 0; i < naliases; i++) { 68 n = strlcpy(pos, e->n_aliases[i], end - pos); 69 if (n >= end - pos) 70 return; 71 r->n_aliases[i] = pos; 72 pos += n + 1; 73 } 74 } 75 76 struct netent * 77 getnetbyname(const char *name) 78 { 79 struct async *as; 80 struct async_res ar; 81 82 as = getnetbyname_async(name, NULL); 83 if (as == NULL) { 84 h_errno = NETDB_INTERNAL; 85 return (NULL); 86 } 87 88 async_run_sync(as, &ar); 89 90 errno = ar.ar_errno; 91 h_errno = ar.ar_h_errno; 92 if (ar.ar_netent == NULL) 93 return (NULL); 94 95 _fillnetent(ar.ar_netent, &_netent, _entbuf, sizeof(_entbuf)); 96 free(ar.ar_netent); 97 98 return (&_netent); 99 } 100 101 struct netent * 102 getnetbyaddr(in_addr_t net, int type) 103 { 104 struct async *as; 105 struct async_res ar; 106 107 as = getnetbyaddr_async(net, type, NULL); 108 if (as == NULL) { 109 h_errno = NETDB_INTERNAL; 110 return (NULL); 111 } 112 113 async_run_sync(as, &ar); 114 115 errno = ar.ar_errno; 116 h_errno = ar.ar_h_errno; 117 if (ar.ar_netent == NULL) 118 return (NULL); 119 120 _fillnetent(ar.ar_netent, &_netent, _entbuf, sizeof(_entbuf)); 121 free(ar.ar_netent); 122 123 return (&_netent); 124 } 125