1*18505Sralph /* gethostnamadr.c 4.9 85/03/25 */ 215662Sralph 3*18505Sralph #include <sys/types.h> 4*18505Sralph #include <sys/socket.h> 5*18505Sralph #include <netinet/in.h> 6*18505Sralph #include <netdb.h> 715662Sralph #include <stdio.h> 8*18505Sralph #include <nameser.h> 9*18505Sralph #include <resolv.h> 1015662Sralph 1115662Sralph #define MAXALIASES 35 1215662Sralph 1315662Sralph static struct hostent host; 1415662Sralph static char *host_aliases[MAXALIASES]; 1515912Sralph static char hostbuf[BUFSIZ+1]; 1615662Sralph 1715662Sralph static struct hostent * 18*18505Sralph getanswer(msg, msglen, iquery) 19*18505Sralph char *msg; 20*18505Sralph int msglen, iquery; 2115662Sralph { 22*18505Sralph register HEADER *hp; 23*18505Sralph register char *cp; 24*18505Sralph register int n; 25*18505Sralph char answer[PACKETSZ]; 26*18505Sralph char *eom, *bp, **ap; 27*18505Sralph int type, class, ancount, buflen; 2815662Sralph 29*18505Sralph n = sendquery(msg, msglen, answer, sizeof(answer)); 30*18505Sralph if (n < 0) { 31*18505Sralph if (_res.options & RES_DEBUG) 32*18505Sralph printf("sendquery failed\n"); 33*18505Sralph return (NULL); 3415662Sralph } 35*18505Sralph eom = answer + n; 36*18505Sralph /* 37*18505Sralph * find first satisfactory answer 38*18505Sralph */ 39*18505Sralph hp = (HEADER *) answer; 40*18505Sralph ancount = ntohs(hp->ancount); 41*18505Sralph if (hp->rcode != NOERROR || ancount == 0) { 42*18505Sralph if (_res.options & RES_DEBUG) 43*18505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 44*18505Sralph return (NULL); 45*18505Sralph } 46*18505Sralph bp = hostbuf; 47*18505Sralph buflen = sizeof(hostbuf); 48*18505Sralph ap = host_aliases; 49*18505Sralph cp = answer + sizeof(HEADER); 50*18505Sralph if (hp->qdcount) { 51*18505Sralph if (iquery) { 52*18505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 53*18505Sralph return (NULL); 54*18505Sralph cp += n + QFIXEDSZ; 55*18505Sralph host.h_name = bp; 56*18505Sralph n = strlen(bp) + 1; 57*18505Sralph bp += n; 58*18505Sralph buflen -= n; 59*18505Sralph } else 60*18505Sralph cp += dn_skip(cp) + QFIXEDSZ; 61*18505Sralph } else if (iquery) 62*18505Sralph return (NULL); 63*18505Sralph while (--ancount >= 0 && cp < eom) { 64*18505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 65*18505Sralph return (NULL); 66*18505Sralph cp += n; 67*18505Sralph type = getshort(cp); 68*18505Sralph cp += sizeof(u_short); 69*18505Sralph class = getshort(cp); 70*18505Sralph cp += sizeof(u_short) + sizeof(u_long); 71*18505Sralph n = getshort(cp); 72*18505Sralph cp += sizeof(u_short); 73*18505Sralph if (type == T_CNAME) { 74*18505Sralph cp += n; 75*18505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 76*18505Sralph continue; 77*18505Sralph *ap++ = bp; 78*18505Sralph n = strlen(bp) + 1; 79*18505Sralph bp += n; 80*18505Sralph buflen -= n; 81*18505Sralph continue; 82*18505Sralph } 83*18505Sralph if (type != T_A || n != 4) { 84*18505Sralph if (_res.options & RES_DEBUG) 85*18505Sralph printf("unexpected answer type %d, size %d\n", 86*18505Sralph type, n); 87*18505Sralph continue; 88*18505Sralph } 89*18505Sralph if (!iquery) { 90*18505Sralph host.h_name = bp; 91*18505Sralph bp += strlen(bp) + 1; 92*18505Sralph } 93*18505Sralph *ap = NULL; 94*18505Sralph host.h_aliases = host_aliases; 95*18505Sralph host.h_addrtype = class == C_IN ? AF_INET : AF_UNSPEC; 96*18505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 97*18505Sralph if (_res.options & RES_DEBUG) 98*18505Sralph printf("size (%d) too big\n", n); 99*18505Sralph return (NULL); 100*18505Sralph } 101*18505Sralph bcopy(cp, host.h_addr = bp, host.h_length = n); 102*18505Sralph return (&host); 103*18505Sralph } 104*18505Sralph return (NULL); 10515662Sralph } 10615662Sralph 10715662Sralph struct hostent * 108*18505Sralph gethostbyname(name) 109*18505Sralph char *name; 11015662Sralph { 111*18505Sralph int n; 11215662Sralph 113*18505Sralph n = mkquery(QUERY, name, C_ANY, T_A, NULL, 0, NULL, hostbuf, sizeof(hostbuf)); 114*18505Sralph if (n < 0) { 115*18505Sralph if (_res.options & RES_DEBUG) 116*18505Sralph printf("mkquery failed\n"); 117*18505Sralph return (NULL); 11817761Sserge } 119*18505Sralph return (getanswer(hostbuf, n, 0)); 12015662Sralph } 12115662Sralph 12215662Sralph struct hostent * 123*18505Sralph gethostbyaddr(addr, len, type) 12415662Sralph char *addr; 125*18505Sralph int len, type; 12615662Sralph { 127*18505Sralph int n; 12815662Sralph 129*18505Sralph if (type != AF_INET) 130*18505Sralph return (NULL); 131*18505Sralph n = mkquery(IQUERY, NULL, C_IN, T_A, addr, len, NULL, hostbuf, sizeof(hostbuf)); 132*18505Sralph if (n < 0) { 133*18505Sralph if (_res.options & RES_DEBUG) 134*18505Sralph printf("mkquery failed\n"); 135*18505Sralph return (NULL); 13617761Sserge } 137*18505Sralph return (getanswer(hostbuf, n, 1)); 13815662Sralph } 139