121374Sdist /* 221374Sdist * Copyright (c) 1983 Regents of the University of California. 321374Sdist * All rights reserved. The Berkeley software License Agreement 421374Sdist * specifies the terms and conditions for redistribution. 521374Sdist */ 615662Sralph 721374Sdist #ifndef lint 8*24508Sbloom static char sccsid[] = "@(#)gethostnamadr.c 5.2 (Berkeley) 09/03/85"; 921374Sdist #endif not lint 1021374Sdist 1118505Sralph #include <sys/types.h> 1218505Sralph #include <sys/socket.h> 1318505Sralph #include <netinet/in.h> 1418505Sralph #include <netdb.h> 1515662Sralph #include <stdio.h> 16*24508Sbloom #include <arpa/nameser.h> 17*24508Sbloom #include <arpa/resolv.h> 1815662Sralph 1915662Sralph #define MAXALIASES 35 2015662Sralph 2115662Sralph static struct hostent host; 2215662Sralph static char *host_aliases[MAXALIASES]; 2315912Sralph static char hostbuf[BUFSIZ+1]; 2415662Sralph 2515662Sralph static struct hostent * 2618505Sralph getanswer(msg, msglen, iquery) 2718505Sralph char *msg; 2818505Sralph int msglen, iquery; 2915662Sralph { 3018505Sralph register HEADER *hp; 3118505Sralph register char *cp; 3218505Sralph register int n; 3318505Sralph char answer[PACKETSZ]; 3418505Sralph char *eom, *bp, **ap; 3518505Sralph int type, class, ancount, buflen; 3615662Sralph 3718531Sralph n = res_send(msg, msglen, answer, sizeof(answer)); 3818505Sralph if (n < 0) { 3918505Sralph if (_res.options & RES_DEBUG) 4018531Sralph printf("res_send failed\n"); 4118505Sralph return (NULL); 4215662Sralph } 4318505Sralph eom = answer + n; 4418505Sralph /* 4518505Sralph * find first satisfactory answer 4618505Sralph */ 4718505Sralph hp = (HEADER *) answer; 4818505Sralph ancount = ntohs(hp->ancount); 4918505Sralph if (hp->rcode != NOERROR || ancount == 0) { 5018505Sralph if (_res.options & RES_DEBUG) 5118505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 5218505Sralph return (NULL); 5318505Sralph } 5418505Sralph bp = hostbuf; 5518505Sralph buflen = sizeof(hostbuf); 5618505Sralph ap = host_aliases; 5718505Sralph cp = answer + sizeof(HEADER); 5818505Sralph if (hp->qdcount) { 5918505Sralph if (iquery) { 6018505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 6118505Sralph return (NULL); 6218505Sralph cp += n + QFIXEDSZ; 6318505Sralph host.h_name = bp; 6418505Sralph n = strlen(bp) + 1; 6518505Sralph bp += n; 6618505Sralph buflen -= n; 6718505Sralph } else 6818505Sralph cp += dn_skip(cp) + QFIXEDSZ; 6918505Sralph } else if (iquery) 7018505Sralph return (NULL); 7118505Sralph while (--ancount >= 0 && cp < eom) { 7218505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 7318505Sralph return (NULL); 7418505Sralph cp += n; 7518505Sralph type = getshort(cp); 7618505Sralph cp += sizeof(u_short); 7718505Sralph class = getshort(cp); 7818505Sralph cp += sizeof(u_short) + sizeof(u_long); 7918505Sralph n = getshort(cp); 8018505Sralph cp += sizeof(u_short); 8118505Sralph if (type == T_CNAME) { 8218505Sralph cp += n; 8318505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 8418505Sralph continue; 8518505Sralph *ap++ = bp; 8618505Sralph n = strlen(bp) + 1; 8718505Sralph bp += n; 8818505Sralph buflen -= n; 8918505Sralph continue; 9018505Sralph } 9118505Sralph if (type != T_A || n != 4) { 9218505Sralph if (_res.options & RES_DEBUG) 9318505Sralph printf("unexpected answer type %d, size %d\n", 9418505Sralph type, n); 9518505Sralph continue; 9618505Sralph } 9718505Sralph if (!iquery) { 9818505Sralph host.h_name = bp; 9918505Sralph bp += strlen(bp) + 1; 10018505Sralph } 10118505Sralph *ap = NULL; 10218505Sralph host.h_aliases = host_aliases; 10318505Sralph host.h_addrtype = class == C_IN ? AF_INET : AF_UNSPEC; 10418505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 10518505Sralph if (_res.options & RES_DEBUG) 10618505Sralph printf("size (%d) too big\n", n); 10718505Sralph return (NULL); 10818505Sralph } 10918505Sralph bcopy(cp, host.h_addr = bp, host.h_length = n); 11018505Sralph return (&host); 11118505Sralph } 11218505Sralph return (NULL); 11315662Sralph } 11415662Sralph 11515662Sralph struct hostent * 11618505Sralph gethostbyname(name) 11718505Sralph char *name; 11815662Sralph { 11918505Sralph int n; 12015662Sralph 12118531Sralph n = res_mkquery(QUERY, name, C_ANY, T_A, NULL, 0, NULL, 12218531Sralph hostbuf, sizeof(hostbuf)); 12318505Sralph if (n < 0) { 12418505Sralph if (_res.options & RES_DEBUG) 12518531Sralph printf("res_mkquery failed\n"); 12618505Sralph return (NULL); 12717761Sserge } 12818505Sralph return (getanswer(hostbuf, n, 0)); 12915662Sralph } 13015662Sralph 13115662Sralph struct hostent * 13218505Sralph gethostbyaddr(addr, len, type) 13315662Sralph char *addr; 13418505Sralph int len, type; 13515662Sralph { 13618505Sralph int n; 13715662Sralph 13818505Sralph if (type != AF_INET) 13918505Sralph return (NULL); 14018531Sralph n = res_mkquery(IQUERY, NULL, C_IN, T_A, addr, len, NULL, 14118531Sralph hostbuf, sizeof(hostbuf)); 14218505Sralph if (n < 0) { 14318505Sralph if (_res.options & RES_DEBUG) 14418531Sralph printf("res_mkquery failed\n"); 14518505Sralph return (NULL); 14617761Sserge } 14718505Sralph return (getanswer(hostbuf, n, 1)); 14815662Sralph } 149