1*18546Sralph /* gethostnamadr.c 4.11 85/04/01 */ 215662Sralph 3*18546Sralph /* 4*18546Sralph * Copyright (c) 1985 Regents of the University of California 5*18546Sralph * All Rights Reserved 6*18546Sralph */ 7*18546Sralph 818505Sralph #include <sys/types.h> 918505Sralph #include <sys/socket.h> 1018505Sralph #include <netinet/in.h> 1118505Sralph #include <netdb.h> 1215662Sralph #include <stdio.h> 1318505Sralph #include <nameser.h> 1418505Sralph #include <resolv.h> 1515662Sralph 1615662Sralph #define MAXALIASES 35 1715662Sralph 1815662Sralph static struct hostent host; 1915662Sralph static char *host_aliases[MAXALIASES]; 2015912Sralph static char hostbuf[BUFSIZ+1]; 2115662Sralph 2215662Sralph static struct hostent * 2318505Sralph getanswer(msg, msglen, iquery) 2418505Sralph char *msg; 2518505Sralph int msglen, iquery; 2615662Sralph { 2718505Sralph register HEADER *hp; 2818505Sralph register char *cp; 2918505Sralph register int n; 3018505Sralph char answer[PACKETSZ]; 3118505Sralph char *eom, *bp, **ap; 3218505Sralph int type, class, ancount, buflen; 3315662Sralph 3418531Sralph n = res_send(msg, msglen, answer, sizeof(answer)); 3518505Sralph if (n < 0) { 3618505Sralph if (_res.options & RES_DEBUG) 3718531Sralph printf("res_send failed\n"); 3818505Sralph return (NULL); 3915662Sralph } 4018505Sralph eom = answer + n; 4118505Sralph /* 4218505Sralph * find first satisfactory answer 4318505Sralph */ 4418505Sralph hp = (HEADER *) answer; 4518505Sralph ancount = ntohs(hp->ancount); 4618505Sralph if (hp->rcode != NOERROR || ancount == 0) { 4718505Sralph if (_res.options & RES_DEBUG) 4818505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 4918505Sralph return (NULL); 5018505Sralph } 5118505Sralph bp = hostbuf; 5218505Sralph buflen = sizeof(hostbuf); 5318505Sralph ap = host_aliases; 5418505Sralph cp = answer + sizeof(HEADER); 5518505Sralph if (hp->qdcount) { 5618505Sralph if (iquery) { 5718505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 5818505Sralph return (NULL); 5918505Sralph cp += n + QFIXEDSZ; 6018505Sralph host.h_name = bp; 6118505Sralph n = strlen(bp) + 1; 6218505Sralph bp += n; 6318505Sralph buflen -= n; 6418505Sralph } else 6518505Sralph cp += dn_skip(cp) + QFIXEDSZ; 6618505Sralph } else if (iquery) 6718505Sralph return (NULL); 6818505Sralph while (--ancount >= 0 && cp < eom) { 6918505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 7018505Sralph return (NULL); 7118505Sralph cp += n; 7218505Sralph type = getshort(cp); 7318505Sralph cp += sizeof(u_short); 7418505Sralph class = getshort(cp); 7518505Sralph cp += sizeof(u_short) + sizeof(u_long); 7618505Sralph n = getshort(cp); 7718505Sralph cp += sizeof(u_short); 7818505Sralph if (type == T_CNAME) { 7918505Sralph cp += n; 8018505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 8118505Sralph continue; 8218505Sralph *ap++ = bp; 8318505Sralph n = strlen(bp) + 1; 8418505Sralph bp += n; 8518505Sralph buflen -= n; 8618505Sralph continue; 8718505Sralph } 8818505Sralph if (type != T_A || n != 4) { 8918505Sralph if (_res.options & RES_DEBUG) 9018505Sralph printf("unexpected answer type %d, size %d\n", 9118505Sralph type, n); 9218505Sralph continue; 9318505Sralph } 9418505Sralph if (!iquery) { 9518505Sralph host.h_name = bp; 9618505Sralph bp += strlen(bp) + 1; 9718505Sralph } 9818505Sralph *ap = NULL; 9918505Sralph host.h_aliases = host_aliases; 10018505Sralph host.h_addrtype = class == C_IN ? AF_INET : AF_UNSPEC; 10118505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 10218505Sralph if (_res.options & RES_DEBUG) 10318505Sralph printf("size (%d) too big\n", n); 10418505Sralph return (NULL); 10518505Sralph } 10618505Sralph bcopy(cp, host.h_addr = bp, host.h_length = n); 10718505Sralph return (&host); 10818505Sralph } 10918505Sralph return (NULL); 11015662Sralph } 11115662Sralph 11215662Sralph struct hostent * 11318505Sralph gethostbyname(name) 11418505Sralph char *name; 11515662Sralph { 11618505Sralph int n; 11715662Sralph 11818531Sralph n = res_mkquery(QUERY, name, C_ANY, T_A, NULL, 0, NULL, 11918531Sralph hostbuf, sizeof(hostbuf)); 12018505Sralph if (n < 0) { 12118505Sralph if (_res.options & RES_DEBUG) 12218531Sralph printf("res_mkquery failed\n"); 12318505Sralph return (NULL); 12417761Sserge } 12518505Sralph return (getanswer(hostbuf, n, 0)); 12615662Sralph } 12715662Sralph 12815662Sralph struct hostent * 12918505Sralph gethostbyaddr(addr, len, type) 13015662Sralph char *addr; 13118505Sralph int len, type; 13215662Sralph { 13318505Sralph int n; 13415662Sralph 13518505Sralph if (type != AF_INET) 13618505Sralph return (NULL); 13718531Sralph n = res_mkquery(IQUERY, NULL, C_IN, T_A, addr, len, NULL, 13818531Sralph hostbuf, sizeof(hostbuf)); 13918505Sralph if (n < 0) { 14018505Sralph if (_res.options & RES_DEBUG) 14118531Sralph printf("res_mkquery failed\n"); 14218505Sralph return (NULL); 14317761Sserge } 14418505Sralph return (getanswer(hostbuf, n, 1)); 14515662Sralph } 146