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*25282Sbloom static char sccsid[] = "@(#)gethostnamadr.c 5.9 (Berkeley) 10/24/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]; 2725153Sbloom static struct in_addr host_addr; 2815662Sralph 2924509Sbloom 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; 4025153Sbloom int type, class, ancount, qdcount, buflen; 4124687Sbloom int haveanswer, getclass; 4224687Sbloom char **hap; 4315662Sralph 4418531Sralph n = res_send(msg, msglen, answer, sizeof(answer)); 4518505Sralph if (n < 0) { 4624733Sbloom #ifdef DEBUG 4718505Sralph if (_res.options & RES_DEBUG) 4818531Sralph printf("res_send failed\n"); 4924733Sbloom #endif 5018505Sralph return (NULL); 5115662Sralph } 5218505Sralph eom = answer + n; 5318505Sralph /* 5418505Sralph * find first satisfactory answer 5518505Sralph */ 5618505Sralph hp = (HEADER *) answer; 5718505Sralph ancount = ntohs(hp->ancount); 5825153Sbloom qdcount = ntohs(hp->qdcount); 5918505Sralph if (hp->rcode != NOERROR || ancount == 0) { 6024733Sbloom #ifdef DEBUG 6118505Sralph if (_res.options & RES_DEBUG) 6218505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 6324733Sbloom #endif 6418505Sralph return (NULL); 6518505Sralph } 6618505Sralph bp = hostbuf; 6718505Sralph buflen = sizeof(hostbuf); 6818505Sralph cp = answer + sizeof(HEADER); 6925153Sbloom if (qdcount) { 7018505Sralph if (iquery) { 7118505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 7218505Sralph return (NULL); 7318505Sralph cp += n + QFIXEDSZ; 7418505Sralph host.h_name = bp; 7518505Sralph n = strlen(bp) + 1; 7618505Sralph bp += n; 7718505Sralph buflen -= n; 7818505Sralph } else 7918505Sralph cp += dn_skip(cp) + QFIXEDSZ; 8025153Sbloom while (--qdcount > 0) 8125153Sbloom cp += dn_skip(cp) + QFIXEDSZ; 8218505Sralph } else if (iquery) 8318505Sralph return (NULL); 8424687Sbloom ap = host_aliases; 8524687Sbloom host.h_aliases = host_aliases; 8624687Sbloom hap = h_addr_ptrs; 8724687Sbloom host.h_addr_list = h_addr_ptrs; 8824687Sbloom haveanswer = 0; 8918505Sralph while (--ancount >= 0 && cp < eom) { 9018505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 9124687Sbloom break; 9218505Sralph cp += n; 9318505Sralph type = getshort(cp); 9418505Sralph cp += sizeof(u_short); 9518505Sralph class = getshort(cp); 9618505Sralph cp += sizeof(u_short) + sizeof(u_long); 9718505Sralph n = getshort(cp); 9818505Sralph cp += sizeof(u_short); 9918505Sralph if (type == T_CNAME) { 10018505Sralph cp += n; 10118505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 10218505Sralph continue; 10318505Sralph *ap++ = bp; 10418505Sralph n = strlen(bp) + 1; 10518505Sralph bp += n; 10618505Sralph buflen -= n; 10718505Sralph continue; 10818505Sralph } 10925153Sbloom if (type == T_PTR) { 11025153Sbloom if ((n = dn_expand(answer, cp, bp, buflen)) < 0) { 11125153Sbloom cp += n; 11225153Sbloom continue; 11325153Sbloom } 11425153Sbloom cp += n; 11525153Sbloom host.h_name = bp; 11625153Sbloom return(&host); 11725153Sbloom } 11824687Sbloom if (type != T_A) { 11924733Sbloom #ifdef DEBUG 12018505Sralph if (_res.options & RES_DEBUG) 12118505Sralph printf("unexpected answer type %d, size %d\n", 12218505Sralph type, n); 12324733Sbloom #endif 12424687Sbloom cp += n; 12518505Sralph continue; 12618505Sralph } 12724687Sbloom if (haveanswer) { 12824687Sbloom if (n != host.h_length) { 12924687Sbloom cp += n; 13024687Sbloom continue; 13124687Sbloom } 13224687Sbloom if (class != getclass) { 13324687Sbloom cp += n; 13424687Sbloom continue; 13524687Sbloom } 13624687Sbloom } else { 13724687Sbloom host.h_length = n; 13824687Sbloom getclass = class; 13924687Sbloom host.h_addrtype = C_IN ? AF_INET : AF_UNSPEC; 14024687Sbloom if (!iquery) { 14124687Sbloom host.h_name = bp; 14224687Sbloom bp += strlen(bp) + 1; 14324687Sbloom } 14418505Sralph } 14518505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 14624733Sbloom #ifdef DEBUG 14718505Sralph if (_res.options & RES_DEBUG) 14818505Sralph printf("size (%d) too big\n", n); 14924733Sbloom #endif 15024687Sbloom break; 15118505Sralph } 15224687Sbloom bcopy(cp, *hap++ = bp, n); 15324687Sbloom bp +=n; 15424687Sbloom cp += n; 15524687Sbloom haveanswer++; 15624687Sbloom } 15724687Sbloom if (haveanswer) { 15824687Sbloom *ap = NULL; 15924687Sbloom *hap = NULL; 16018505Sralph return (&host); 16124687Sbloom } else 16224687Sbloom return (NULL); 16315662Sralph } 16415662Sralph 16515662Sralph struct hostent * 16618505Sralph gethostbyname(name) 16718505Sralph char *name; 16815662Sralph { 16918505Sralph int n; 17024687Sbloom char buf[BUFSIZ+1]; 17115662Sralph 17224687Sbloom n = res_mkquery(QUERY, name, C_ANY, T_A, (char *)NULL, 0, NULL, 17324713Sbloom buf, sizeof(buf)); 17418505Sralph if (n < 0) { 17524733Sbloom #ifdef DEBUG 17618505Sralph if (_res.options & RES_DEBUG) 17718531Sralph printf("res_mkquery failed\n"); 17824733Sbloom #endif 17918505Sralph return (NULL); 18017761Sserge } 18124687Sbloom return(getanswer(buf, n, 0)); 18215662Sralph } 18315662Sralph 18415662Sralph struct hostent * 18518505Sralph gethostbyaddr(addr, len, type) 18615662Sralph char *addr; 18718505Sralph int len, type; 18815662Sralph { 18918505Sralph int n; 19024687Sbloom char buf[BUFSIZ+1]; 19125153Sbloom register struct hostent *hp; 19225153Sbloom char qbuf[MAXDNAME]; 19315662Sralph 19418505Sralph if (type != AF_INET) 19518505Sralph return (NULL); 19625153Sbloom (void)sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa", 19725153Sbloom (*(unsigned *)addr >> 24 & 0xff), 19825153Sbloom (*(unsigned *)addr >> 16 & 0xff), 19925153Sbloom (*(unsigned *)addr >> 8 & 0xff), 20025153Sbloom (*(unsigned *)addr & 0xff)); 20125153Sbloom n = res_mkquery(QUERY, qbuf, C_IN, T_PTR, NULL, 0, NULL, 20224713Sbloom buf, sizeof(buf)); 20318505Sralph if (n < 0) { 20424733Sbloom #ifdef DEBUG 20518505Sralph if (_res.options & RES_DEBUG) 20618531Sralph printf("res_mkquery failed\n"); 20724733Sbloom #endif 20818505Sralph return (NULL); 20917761Sserge } 21025153Sbloom if ((hp = getanswer(buf, n, 1)) == NULL) 21125153Sbloom return(NULL); 21225153Sbloom hp->h_addrtype = type; 21325153Sbloom hp->h_length = len; 214*25282Sbloom h_addr_ptrs[0] = (char *)&host_addr; 21525153Sbloom h_addr_ptrs[1] = (char *)0; 21625153Sbloom host_addr = *(struct in_addr *)addr; 21725153Sbloom return(hp); 21815662Sralph } 219