1*21374Sdist /* 2*21374Sdist * Copyright (c) 1983 Regents of the University of California. 3*21374Sdist * All rights reserved. The Berkeley software License Agreement 4*21374Sdist * specifies the terms and conditions for redistribution. 5*21374Sdist */ 615662Sralph 7*21374Sdist #ifndef lint 8*21374Sdist static char sccsid[] = "@(#)gethostnamadr.c 5.1 (Berkeley) 05/30/85"; 9*21374Sdist #endif not lint 10*21374Sdist 1118546Sralph /* 1218546Sralph * Copyright (c) 1985 Regents of the University of California 1318546Sralph * All Rights Reserved 1418546Sralph */ 1518546Sralph 1618505Sralph #include <sys/types.h> 1718505Sralph #include <sys/socket.h> 1818505Sralph #include <netinet/in.h> 1918505Sralph #include <netdb.h> 2015662Sralph #include <stdio.h> 2118505Sralph #include <nameser.h> 2218505Sralph #include <resolv.h> 2315662Sralph 2415662Sralph #define MAXALIASES 35 2515662Sralph 2615662Sralph static struct hostent host; 2715662Sralph static char *host_aliases[MAXALIASES]; 2815912Sralph static char hostbuf[BUFSIZ+1]; 2915662Sralph 3015662Sralph static struct hostent * 3118505Sralph getanswer(msg, msglen, iquery) 3218505Sralph char *msg; 3318505Sralph int msglen, iquery; 3415662Sralph { 3518505Sralph register HEADER *hp; 3618505Sralph register char *cp; 3718505Sralph register int n; 3818505Sralph char answer[PACKETSZ]; 3918505Sralph char *eom, *bp, **ap; 4018505Sralph int type, class, ancount, buflen; 4115662Sralph 4218531Sralph n = res_send(msg, msglen, answer, sizeof(answer)); 4318505Sralph if (n < 0) { 4418505Sralph if (_res.options & RES_DEBUG) 4518531Sralph printf("res_send failed\n"); 4618505Sralph return (NULL); 4715662Sralph } 4818505Sralph eom = answer + n; 4918505Sralph /* 5018505Sralph * find first satisfactory answer 5118505Sralph */ 5218505Sralph hp = (HEADER *) answer; 5318505Sralph ancount = ntohs(hp->ancount); 5418505Sralph if (hp->rcode != NOERROR || ancount == 0) { 5518505Sralph if (_res.options & RES_DEBUG) 5618505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 5718505Sralph return (NULL); 5818505Sralph } 5918505Sralph bp = hostbuf; 6018505Sralph buflen = sizeof(hostbuf); 6118505Sralph ap = host_aliases; 6218505Sralph cp = answer + sizeof(HEADER); 6318505Sralph if (hp->qdcount) { 6418505Sralph if (iquery) { 6518505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 6618505Sralph return (NULL); 6718505Sralph cp += n + QFIXEDSZ; 6818505Sralph host.h_name = bp; 6918505Sralph n = strlen(bp) + 1; 7018505Sralph bp += n; 7118505Sralph buflen -= n; 7218505Sralph } else 7318505Sralph cp += dn_skip(cp) + QFIXEDSZ; 7418505Sralph } else if (iquery) 7518505Sralph return (NULL); 7618505Sralph while (--ancount >= 0 && cp < eom) { 7718505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 7818505Sralph return (NULL); 7918505Sralph cp += n; 8018505Sralph type = getshort(cp); 8118505Sralph cp += sizeof(u_short); 8218505Sralph class = getshort(cp); 8318505Sralph cp += sizeof(u_short) + sizeof(u_long); 8418505Sralph n = getshort(cp); 8518505Sralph cp += sizeof(u_short); 8618505Sralph if (type == T_CNAME) { 8718505Sralph cp += n; 8818505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 8918505Sralph continue; 9018505Sralph *ap++ = bp; 9118505Sralph n = strlen(bp) + 1; 9218505Sralph bp += n; 9318505Sralph buflen -= n; 9418505Sralph continue; 9518505Sralph } 9618505Sralph if (type != T_A || n != 4) { 9718505Sralph if (_res.options & RES_DEBUG) 9818505Sralph printf("unexpected answer type %d, size %d\n", 9918505Sralph type, n); 10018505Sralph continue; 10118505Sralph } 10218505Sralph if (!iquery) { 10318505Sralph host.h_name = bp; 10418505Sralph bp += strlen(bp) + 1; 10518505Sralph } 10618505Sralph *ap = NULL; 10718505Sralph host.h_aliases = host_aliases; 10818505Sralph host.h_addrtype = class == C_IN ? AF_INET : AF_UNSPEC; 10918505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 11018505Sralph if (_res.options & RES_DEBUG) 11118505Sralph printf("size (%d) too big\n", n); 11218505Sralph return (NULL); 11318505Sralph } 11418505Sralph bcopy(cp, host.h_addr = bp, host.h_length = n); 11518505Sralph return (&host); 11618505Sralph } 11718505Sralph return (NULL); 11815662Sralph } 11915662Sralph 12015662Sralph struct hostent * 12118505Sralph gethostbyname(name) 12218505Sralph char *name; 12315662Sralph { 12418505Sralph int n; 12515662Sralph 12618531Sralph n = res_mkquery(QUERY, name, C_ANY, T_A, NULL, 0, NULL, 12718531Sralph hostbuf, sizeof(hostbuf)); 12818505Sralph if (n < 0) { 12918505Sralph if (_res.options & RES_DEBUG) 13018531Sralph printf("res_mkquery failed\n"); 13118505Sralph return (NULL); 13217761Sserge } 13318505Sralph return (getanswer(hostbuf, n, 0)); 13415662Sralph } 13515662Sralph 13615662Sralph struct hostent * 13718505Sralph gethostbyaddr(addr, len, type) 13815662Sralph char *addr; 13918505Sralph int len, type; 14015662Sralph { 14118505Sralph int n; 14215662Sralph 14318505Sralph if (type != AF_INET) 14418505Sralph return (NULL); 14518531Sralph n = res_mkquery(IQUERY, NULL, C_IN, T_A, addr, len, NULL, 14618531Sralph hostbuf, sizeof(hostbuf)); 14718505Sralph if (n < 0) { 14818505Sralph if (_res.options & RES_DEBUG) 14918531Sralph printf("res_mkquery failed\n"); 15018505Sralph return (NULL); 15117761Sserge } 15218505Sralph return (getanswer(hostbuf, n, 1)); 15315662Sralph } 154