getnetbydns.c revision 13408
13070Spst/*- 23070Spst * Copyright (c) 1985, 1988, 1993 33070Spst * The Regents of the University of California. All rights reserved. 43070Spst * 53070Spst * Redistribution and use in source and binary forms, with or without 63070Spst * modification, are permitted provided that the following conditions 73070Spst * are met: 83070Spst * 1. Redistributions of source code must retain the above copyright 93070Spst * notice, this list of conditions and the following disclaimer. 103070Spst * 2. Redistributions in binary form must reproduce the above copyright 113070Spst * notice, this list of conditions and the following disclaimer in the 123070Spst * documentation and/or other materials provided with the distribution. 133070Spst * 3. All advertising materials mentioning features or use of this software 143070Spst * must display the following acknowledgement: 153070Spst * This product includes software developed by the University of 163070Spst * California, Berkeley and its contributors. 173070Spst * 4. Neither the name of the University nor the names of its contributors 183070Spst * may be used to endorse or promote products derived from this software 193070Spst * without specific prior written permission. 203070Spst * 213070Spst * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 223070Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 233070Spst * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 243070Spst * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 253070Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 263070Spst * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 273070Spst * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 283070Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 293070Spst * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 303070Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 313070Spst * SUCH DAMAGE. 323070Spst * - 333070Spst * Portions Copyright (c) 1993 by Digital Equipment Corporation. 348870Srgrimes * 353070Spst * Permission to use, copy, modify, and distribute this software for any 363070Spst * purpose with or without fee is hereby granted, provided that the above 373070Spst * copyright notice and this permission notice appear in all copies, and that 383070Spst * the name of Digital Equipment Corporation not be used in advertising or 393070Spst * publicity pertaining to distribution of the document or software without 403070Spst * specific, written prior permission. 418870Srgrimes * 423070Spst * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL 433070Spst * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES 443070Spst * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT 453070Spst * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 463070Spst * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 473070Spst * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 483070Spst * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 493070Spst * SOFTWARE. 503070Spst * - 513070Spst * --Copyright-- 523070Spst */ 5313408Speter/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro 5413408Speter * Dep. Matematica Universidade de Coimbra, Portugal, Europe 5513408Speter * 5613408Speter * Permission to use, copy, modify, and distribute this software for any 5713408Speter * purpose with or without fee is hereby granted, provided that the above 5813408Speter * copyright notice and this permission notice appear in all copies. 5913408Speter */ 603070Spst 613070Spst#if defined(LIBC_SCCS) && !defined(lint) 623070Spststatic char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; 6313408Speterstatic char rcsid[] = "$Id: getnetbydns.c,v 1.4 1995/10/22 14:39:04 phk Exp $"; 643070Spst#endif /* LIBC_SCCS and not lint */ 653070Spst 663070Spst#include <sys/param.h> 673070Spst#include <sys/socket.h> 683070Spst#include <netinet/in.h> 693070Spst#include <arpa/inet.h> 703070Spst#include <arpa/nameser.h> 7113408Speter 7213408Speter#include <stdio.h> 733070Spst#include <netdb.h> 743070Spst#include <resolv.h> 753070Spst#include <ctype.h> 763070Spst#include <errno.h> 773070Spst#include <string.h> 7813408Speter#include <unistd.h> 793070Spst#include <syslog.h> 803070Spst 8113408Speter#include "res_config.h" 823070Spst 8313408Speterextern int h_errno; 8413408Speter 8513408Speter#define BYADDR 0 8613408Speter#define BYNAME 1 873070Spst#define MAXALIASES 35 883070Spst 893070Spst#if PACKETSZ > 1024 903070Spst#define MAXPACKET PACKETSZ 913070Spst#else 923070Spst#define MAXPACKET 1024 933070Spst#endif 943070Spst 953070Spsttypedef union { 9613408Speter HEADER hdr; 9713408Speter u_char buf[MAXPACKET]; 983070Spst} querybuf; 993070Spst 1003070Spsttypedef union { 10113408Speter long al; 10213408Speter char ac; 1033070Spst} align; 1043070Spst 1053070Spststatic struct netent * 1063070Spstgetnetanswer(answer, anslen, net_i) 1073070Spst querybuf *answer; 1083070Spst int anslen; 1093070Spst int net_i; 1103070Spst{ 1113070Spst 11213408Speter register HEADER *hp; 11313408Speter register u_char *cp; 11413408Speter register int n; 11513408Speter u_char *eom; 11613408Speter int type, class, buflen, ancount, qdcount, haveanswer, i, nchar; 11713408Speter char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap, 11813408Speter *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0; 11913408Speterstatic struct netent net_entry; 12013408Speterstatic char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; 1213070Spst 1223070Spst /* 1233070Spst * find first satisfactory answer 1243070Spst * 1253070Spst * answer --> +------------+ ( MESSAGE ) 1263070Spst * | Header | 1273070Spst * +------------+ 1283070Spst * | Question | the question for the name server 1293070Spst * +------------+ 1303070Spst * | Answer | RRs answering the question 1313070Spst * +------------+ 1323070Spst * | Authority | RRs pointing toward an authority 1333070Spst * | Additional | RRs holding additional information 1343070Spst * +------------+ 1353070Spst */ 1363070Spst eom = answer->buf + anslen; 1373070Spst hp = &answer->hdr; 1383070Spst ancount = ntohs(hp->ancount); /* #/records in the answer section */ 1393070Spst qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ 1403070Spst bp = netbuf; 1413070Spst buflen = sizeof(netbuf); 1423070Spst cp = answer->buf + HFIXEDSZ; 1433070Spst if (!qdcount) { 1443070Spst if (hp->aa) 1453070Spst h_errno = HOST_NOT_FOUND; 1463070Spst else 1473070Spst h_errno = TRY_AGAIN; 14813408Speter return (NULL); 1493070Spst } 15013408Speter while (qdcount-- > 0) 1513070Spst cp += __dn_skipname(cp, eom) + QFIXEDSZ; 1523070Spst ap = net_aliases; 1533070Spst *ap = NULL; 1543070Spst net_entry.n_aliases = net_aliases; 1553070Spst haveanswer = 0; 1563070Spst while (--ancount >= 0 && cp < eom) { 1573070Spst n = dn_expand(answer->buf, eom, cp, bp, buflen); 1583070Spst if (n < 0) 1593070Spst break; 1603070Spst cp += n; 1613070Spst ans[0] = '\0'; 1623070Spst (void)strcpy(&ans[0], bp); 1633070Spst GETSHORT(type, cp); 1643070Spst GETSHORT(class, cp); 1653070Spst cp += INT32SZ; /* TTL */ 1663070Spst GETSHORT(n, cp); 1673070Spst if (class == C_IN && type == T_PTR) { 1683070Spst n = dn_expand(answer->buf, eom, cp, bp, buflen); 1693070Spst if (n < 0) { 1703070Spst cp += n; 1713070Spst return (NULL); 1723070Spst } 17313408Speter cp += n; 1743070Spst *ap++ = bp; 17513408Speter bp += strlen(bp) + 1; 17613408Speter net_entry.n_addrtype = 17713408Speter (class == C_IN) ? AF_INET : AF_UNSPEC; 1783070Spst haveanswer++; 1793070Spst } 1803070Spst } 1813070Spst if (haveanswer) { 1823070Spst *ap = NULL; 1833070Spst switch (net_i) { 18413408Speter case BYADDR: 1853070Spst net_entry.n_name = *net_entry.n_aliases; 1863070Spst net_entry.n_net = 0L; 1873070Spst break; 18813408Speter case BYNAME: 1893070Spst in = *net_entry.n_aliases; 1903070Spst net_entry.n_name = &ans[0]; 1913070Spst aux2[0] = '\0'; 19213408Speter for (i = 0; i < 4; i++) { 1933070Spst for (st = in, nchar = 0; 1943070Spst *st != '.'; 1953070Spst st++, nchar++) 1963070Spst ; 1973070Spst if (nchar != 1 || *in != '0' || flag) { 1983070Spst flag = 1; 1993070Spst (void)strncpy(paux1, 20013408Speter (i==0) ? in : in-1, 20113408Speter (i==0) ?nchar : nchar+1); 20213408Speter paux1[(i==0) ? nchar : nchar+1] = '\0'; 2033070Spst pauxt = paux2; 2043070Spst paux2 = strcat(paux1, paux2); 2053070Spst paux1 = pauxt; 2063070Spst } 2073070Spst in = ++st; 20813408Speter } 2093070Spst net_entry.n_net = inet_network(paux2); 21013408Speter break; 2113070Spst } 2123070Spst net_entry.n_aliases++; 2133070Spst return (&net_entry); 2143070Spst } 21513408Speter h_errno = TRY_AGAIN; 21613408Speter return (NULL); 2173070Spst} 2183070Spst 2193070Spststruct netent * 2203070Spst_getnetbydnsaddr(net, net_type) 2213070Spst register long net; 2223070Spst register int net_type; 2233070Spst{ 22413408Speter unsigned int netbr[4]; 22513408Speter int nn, anslen; 22613408Speter querybuf buf; 22713408Speter char qbuf[MAXDNAME]; 22813408Speter unsigned long net2; 22913408Speter struct netent *net_entry; 2303070Spst 2313070Spst if (net_type != AF_INET) 2323070Spst return (NULL); 2333070Spst 23413408Speter for (nn = 4, net2 = net; net2; net2 >>= 8) 2353070Spst netbr[--nn] = net2 & 0xff; 2363070Spst switch (nn) { 23713408Speter case 3: /* Class A */ 23813408Speter sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]); 23913408Speter break; 24013408Speter case 2: /* Class B */ 24113408Speter sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]); 24213408Speter break; 24313408Speter case 1: /* Class C */ 24413408Speter sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2], 24513408Speter netbr[1]); 24613408Speter break; 24713408Speter case 0: /* Class D - E */ 24813408Speter sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2], 24913408Speter netbr[1], netbr[0]); 25013408Speter break; 2513070Spst } 25213408Speter anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); 2533070Spst if (anslen < 0) { 25413408Speter#ifdef DEBUG 2553070Spst if (_res.options & RES_DEBUG) 2563070Spst printf("res_query failed\n"); 25713408Speter#endif 2583070Spst return (NULL); 2593070Spst } 2603070Spst net_entry = getnetanswer(&buf, anslen, BYADDR); 2613070Spst if (net_entry) { 2623070Spst unsigned u_net = net; /* maybe net should be unsigned ? */ 2633070Spst 2643070Spst /* Strip trailing zeros */ 26513408Speter while ((u_net & 0xff) == 0 && u_net != 0) 2663070Spst u_net >>= 8; 2673070Spst net_entry->n_net = u_net; 26813408Speter return (net_entry); 2693070Spst } 27013408Speter return (NULL); 2713070Spst} 2723070Spst 2733070Spststruct netent * 2743070Spst_getnetbydnsname(net) 2753070Spst register const char *net; 2763070Spst{ 27713408Speter int anslen; 27813408Speter querybuf buf; 27913408Speter char qbuf[MAXDNAME]; 2808870Srgrimes 28113408Speter if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 28213408Speter h_errno = NETDB_INTERNAL; 28313408Speter return (NULL); 28413408Speter } 28513408Speter strcpy(&qbuf[0], net); 28613408Speter anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); 2873070Spst if (anslen < 0) { 28813408Speter#ifdef DEBUG 2893070Spst if (_res.options & RES_DEBUG) 2903070Spst printf("res_query failed\n"); 29113408Speter#endif 29213408Speter return (NULL); 2933070Spst } 2943070Spst return getnetanswer(&buf, anslen, BYNAME); 2953070Spst} 2963070Spst 2973070Spstvoid 2983070Spst_setnetdnsent(stayopen) 2993070Spst int stayopen; 3003070Spst{ 3013070Spst if (stayopen) 3023070Spst _res.options |= RES_STAYOPEN | RES_USEVC; 3033070Spst} 3043070Spst 3053070Spstvoid 3063070Spst_endnetdnsent() 3073070Spst{ 3083070Spst _res.options &= ~(RES_STAYOPEN | RES_USEVC); 3093070Spst _res_close(); 3103070Spst} 311