121374Sdist /* 224687Sbloom * 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*24733Sbloom static char sccsid[] = "@(#)gethostnamadr.c 5.7 (Berkeley) 09/14/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> 1624508Sbloom #include <arpa/nameser.h> 1724508Sbloom #include <arpa/resolv.h> 1815662Sralph 1915662Sralph #define MAXALIASES 35 2024687Sbloom #define MAXADDRS 35 2115662Sralph 2224687Sbloom static char *h_addr_ptrs[MAXADDRS + 1]; 2324687Sbloom 2424687Sbloom static struct hostent host; 2515662Sralph static char *host_aliases[MAXALIASES]; 2615912Sralph static char hostbuf[BUFSIZ+1]; 2715662Sralph 2824509Sbloom 2915662Sralph static struct hostent * 3018505Sralph getanswer(msg, msglen, iquery) 3118505Sralph char *msg; 3218505Sralph int msglen, iquery; 3315662Sralph { 3418505Sralph register HEADER *hp; 3518505Sralph register char *cp; 3618505Sralph register int n; 3718505Sralph char answer[PACKETSZ]; 3818505Sralph char *eom, *bp, **ap; 3918505Sralph int type, class, ancount, buflen; 4024687Sbloom int haveanswer, getclass; 4124687Sbloom char **hap; 4215662Sralph 4318531Sralph n = res_send(msg, msglen, answer, sizeof(answer)); 4418505Sralph if (n < 0) { 45*24733Sbloom #ifdef DEBUG 4618505Sralph if (_res.options & RES_DEBUG) 4718531Sralph printf("res_send failed\n"); 48*24733Sbloom #endif 4918505Sralph return (NULL); 5015662Sralph } 5118505Sralph eom = answer + n; 5218505Sralph /* 5318505Sralph * find first satisfactory answer 5418505Sralph */ 5518505Sralph hp = (HEADER *) answer; 5618505Sralph ancount = ntohs(hp->ancount); 5718505Sralph if (hp->rcode != NOERROR || ancount == 0) { 58*24733Sbloom #ifdef DEBUG 5918505Sralph if (_res.options & RES_DEBUG) 6018505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 61*24733Sbloom #endif 6218505Sralph return (NULL); 6318505Sralph } 6418505Sralph bp = hostbuf; 6518505Sralph buflen = sizeof(hostbuf); 6618505Sralph cp = answer + sizeof(HEADER); 6718505Sralph if (hp->qdcount) { 6818505Sralph if (iquery) { 6918505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 7018505Sralph return (NULL); 7118505Sralph cp += n + QFIXEDSZ; 7218505Sralph host.h_name = bp; 7318505Sralph n = strlen(bp) + 1; 7418505Sralph bp += n; 7518505Sralph buflen -= n; 7618505Sralph } else 7718505Sralph cp += dn_skip(cp) + QFIXEDSZ; 7818505Sralph } else if (iquery) 7918505Sralph return (NULL); 8024687Sbloom ap = host_aliases; 8124687Sbloom host.h_aliases = host_aliases; 8224687Sbloom hap = h_addr_ptrs; 8324687Sbloom host.h_addr_list = h_addr_ptrs; 8424687Sbloom haveanswer = 0; 8518505Sralph while (--ancount >= 0 && cp < eom) { 8618505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 8724687Sbloom break; 8818505Sralph cp += n; 8918505Sralph type = getshort(cp); 9018505Sralph cp += sizeof(u_short); 9118505Sralph class = getshort(cp); 9218505Sralph cp += sizeof(u_short) + sizeof(u_long); 9318505Sralph n = getshort(cp); 9418505Sralph cp += sizeof(u_short); 9518505Sralph if (type == T_CNAME) { 9618505Sralph cp += n; 9718505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 9818505Sralph continue; 9918505Sralph *ap++ = bp; 10018505Sralph n = strlen(bp) + 1; 10118505Sralph bp += n; 10218505Sralph buflen -= n; 10318505Sralph continue; 10418505Sralph } 10524687Sbloom if (type != T_A) { 106*24733Sbloom #ifdef DEBUG 10718505Sralph if (_res.options & RES_DEBUG) 10818505Sralph printf("unexpected answer type %d, size %d\n", 10918505Sralph type, n); 110*24733Sbloom #endif 11124687Sbloom cp += n; 11218505Sralph continue; 11318505Sralph } 11424687Sbloom if (haveanswer) { 11524687Sbloom if (n != host.h_length) { 11624687Sbloom cp += n; 11724687Sbloom continue; 11824687Sbloom } 11924687Sbloom if (class != getclass) { 12024687Sbloom cp += n; 12124687Sbloom continue; 12224687Sbloom } 12324687Sbloom } else { 12424687Sbloom host.h_length = n; 12524687Sbloom getclass = class; 12624687Sbloom host.h_addrtype = C_IN ? AF_INET : AF_UNSPEC; 12724687Sbloom if (!iquery) { 12824687Sbloom host.h_name = bp; 12924687Sbloom bp += strlen(bp) + 1; 13024687Sbloom } 13118505Sralph } 13218505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 133*24733Sbloom #ifdef DEBUG 13418505Sralph if (_res.options & RES_DEBUG) 13518505Sralph printf("size (%d) too big\n", n); 136*24733Sbloom #endif 13724687Sbloom break; 13818505Sralph } 13924687Sbloom bcopy(cp, *hap++ = bp, n); 14024687Sbloom bp +=n; 14124687Sbloom cp += n; 14224687Sbloom haveanswer++; 14324687Sbloom } 14424687Sbloom if (haveanswer) { 14524687Sbloom *ap = NULL; 14624687Sbloom *hap = NULL; 14718505Sralph return (&host); 14824687Sbloom } else 14924687Sbloom return (NULL); 15015662Sralph } 15115662Sralph 15215662Sralph struct hostent * 15318505Sralph gethostbyname(name) 15418505Sralph char *name; 15515662Sralph { 15618505Sralph int n; 15724687Sbloom char buf[BUFSIZ+1]; 15815662Sralph 15924687Sbloom n = res_mkquery(QUERY, name, C_ANY, T_A, (char *)NULL, 0, NULL, 16024713Sbloom buf, sizeof(buf)); 16118505Sralph if (n < 0) { 162*24733Sbloom #ifdef DEBUG 16318505Sralph if (_res.options & RES_DEBUG) 16418531Sralph printf("res_mkquery failed\n"); 165*24733Sbloom #endif 16618505Sralph return (NULL); 16717761Sserge } 16824687Sbloom return(getanswer(buf, n, 0)); 16915662Sralph } 17015662Sralph 17115662Sralph struct hostent * 17218505Sralph gethostbyaddr(addr, len, type) 17315662Sralph char *addr; 17418505Sralph int len, type; 17515662Sralph { 17618505Sralph int n; 17724687Sbloom char buf[BUFSIZ+1]; 17815662Sralph 17918505Sralph if (type != AF_INET) 18018505Sralph return (NULL); 18124687Sbloom n = res_mkquery(IQUERY, (char *)NULL, C_IN, T_A, addr, len, NULL, 18224713Sbloom buf, sizeof(buf)); 18318505Sralph if (n < 0) { 184*24733Sbloom #ifdef DEBUG 18518505Sralph if (_res.options & RES_DEBUG) 18618531Sralph printf("res_mkquery failed\n"); 187*24733Sbloom #endif 18818505Sralph return (NULL); 18917761Sserge } 19024687Sbloom return(getanswer(buf, n, 1)); 19115662Sralph } 19224509Sbloom 19324509Sbloom 194