1*18531Sralph /* gethostnamadr.c 4.10 85/03/28 */ 215662Sralph 318505Sralph #include <sys/types.h> 418505Sralph #include <sys/socket.h> 518505Sralph #include <netinet/in.h> 618505Sralph #include <netdb.h> 715662Sralph #include <stdio.h> 818505Sralph #include <nameser.h> 918505Sralph #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 * 1818505Sralph getanswer(msg, msglen, iquery) 1918505Sralph char *msg; 2018505Sralph int msglen, iquery; 2115662Sralph { 2218505Sralph register HEADER *hp; 2318505Sralph register char *cp; 2418505Sralph register int n; 2518505Sralph char answer[PACKETSZ]; 2618505Sralph char *eom, *bp, **ap; 2718505Sralph int type, class, ancount, buflen; 2815662Sralph 29*18531Sralph n = res_send(msg, msglen, answer, sizeof(answer)); 3018505Sralph if (n < 0) { 3118505Sralph if (_res.options & RES_DEBUG) 32*18531Sralph printf("res_send failed\n"); 3318505Sralph return (NULL); 3415662Sralph } 3518505Sralph eom = answer + n; 3618505Sralph /* 3718505Sralph * find first satisfactory answer 3818505Sralph */ 3918505Sralph hp = (HEADER *) answer; 4018505Sralph ancount = ntohs(hp->ancount); 4118505Sralph if (hp->rcode != NOERROR || ancount == 0) { 4218505Sralph if (_res.options & RES_DEBUG) 4318505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 4418505Sralph return (NULL); 4518505Sralph } 4618505Sralph bp = hostbuf; 4718505Sralph buflen = sizeof(hostbuf); 4818505Sralph ap = host_aliases; 4918505Sralph cp = answer + sizeof(HEADER); 5018505Sralph if (hp->qdcount) { 5118505Sralph if (iquery) { 5218505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 5318505Sralph return (NULL); 5418505Sralph cp += n + QFIXEDSZ; 5518505Sralph host.h_name = bp; 5618505Sralph n = strlen(bp) + 1; 5718505Sralph bp += n; 5818505Sralph buflen -= n; 5918505Sralph } else 6018505Sralph cp += dn_skip(cp) + QFIXEDSZ; 6118505Sralph } else if (iquery) 6218505Sralph return (NULL); 6318505Sralph while (--ancount >= 0 && cp < eom) { 6418505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 6518505Sralph return (NULL); 6618505Sralph cp += n; 6718505Sralph type = getshort(cp); 6818505Sralph cp += sizeof(u_short); 6918505Sralph class = getshort(cp); 7018505Sralph cp += sizeof(u_short) + sizeof(u_long); 7118505Sralph n = getshort(cp); 7218505Sralph cp += sizeof(u_short); 7318505Sralph if (type == T_CNAME) { 7418505Sralph cp += n; 7518505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 7618505Sralph continue; 7718505Sralph *ap++ = bp; 7818505Sralph n = strlen(bp) + 1; 7918505Sralph bp += n; 8018505Sralph buflen -= n; 8118505Sralph continue; 8218505Sralph } 8318505Sralph if (type != T_A || n != 4) { 8418505Sralph if (_res.options & RES_DEBUG) 8518505Sralph printf("unexpected answer type %d, size %d\n", 8618505Sralph type, n); 8718505Sralph continue; 8818505Sralph } 8918505Sralph if (!iquery) { 9018505Sralph host.h_name = bp; 9118505Sralph bp += strlen(bp) + 1; 9218505Sralph } 9318505Sralph *ap = NULL; 9418505Sralph host.h_aliases = host_aliases; 9518505Sralph host.h_addrtype = class == C_IN ? AF_INET : AF_UNSPEC; 9618505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 9718505Sralph if (_res.options & RES_DEBUG) 9818505Sralph printf("size (%d) too big\n", n); 9918505Sralph return (NULL); 10018505Sralph } 10118505Sralph bcopy(cp, host.h_addr = bp, host.h_length = n); 10218505Sralph return (&host); 10318505Sralph } 10418505Sralph return (NULL); 10515662Sralph } 10615662Sralph 10715662Sralph struct hostent * 10818505Sralph gethostbyname(name) 10918505Sralph char *name; 11015662Sralph { 11118505Sralph int n; 11215662Sralph 113*18531Sralph n = res_mkquery(QUERY, name, C_ANY, T_A, NULL, 0, NULL, 114*18531Sralph hostbuf, sizeof(hostbuf)); 11518505Sralph if (n < 0) { 11618505Sralph if (_res.options & RES_DEBUG) 117*18531Sralph printf("res_mkquery failed\n"); 11818505Sralph return (NULL); 11917761Sserge } 12018505Sralph return (getanswer(hostbuf, n, 0)); 12115662Sralph } 12215662Sralph 12315662Sralph struct hostent * 12418505Sralph gethostbyaddr(addr, len, type) 12515662Sralph char *addr; 12618505Sralph int len, type; 12715662Sralph { 12818505Sralph int n; 12915662Sralph 13018505Sralph if (type != AF_INET) 13118505Sralph return (NULL); 132*18531Sralph n = res_mkquery(IQUERY, NULL, C_IN, T_A, addr, len, NULL, 133*18531Sralph hostbuf, sizeof(hostbuf)); 13418505Sralph if (n < 0) { 13518505Sralph if (_res.options & RES_DEBUG) 136*18531Sralph printf("res_mkquery failed\n"); 13718505Sralph return (NULL); 13817761Sserge } 13918505Sralph return (getanswer(hostbuf, n, 1)); 14015662Sralph } 141