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*24713Sbloom static char sccsid[] = "@(#)gethostnamadr.c 5.6 (Berkeley) 09/12/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) { 4518505Sralph if (_res.options & RES_DEBUG) 4618531Sralph printf("res_send failed\n"); 4718505Sralph return (NULL); 4815662Sralph } 4918505Sralph eom = answer + n; 5018505Sralph /* 5118505Sralph * find first satisfactory answer 5218505Sralph */ 5318505Sralph hp = (HEADER *) answer; 5418505Sralph ancount = ntohs(hp->ancount); 5518505Sralph if (hp->rcode != NOERROR || ancount == 0) { 5618505Sralph if (_res.options & RES_DEBUG) 5718505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 5818505Sralph return (NULL); 5918505Sralph } 6018505Sralph bp = hostbuf; 6118505Sralph buflen = sizeof(hostbuf); 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); 7624687Sbloom ap = host_aliases; 7724687Sbloom host.h_aliases = host_aliases; 7824687Sbloom hap = h_addr_ptrs; 7924687Sbloom host.h_addr_list = h_addr_ptrs; 8024687Sbloom haveanswer = 0; 8118505Sralph while (--ancount >= 0 && cp < eom) { 8218505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 8324687Sbloom break; 8418505Sralph cp += n; 8518505Sralph type = getshort(cp); 8618505Sralph cp += sizeof(u_short); 8718505Sralph class = getshort(cp); 8818505Sralph cp += sizeof(u_short) + sizeof(u_long); 8918505Sralph n = getshort(cp); 9018505Sralph cp += sizeof(u_short); 9118505Sralph if (type == T_CNAME) { 9218505Sralph cp += n; 9318505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 9418505Sralph continue; 9518505Sralph *ap++ = bp; 9618505Sralph n = strlen(bp) + 1; 9718505Sralph bp += n; 9818505Sralph buflen -= n; 9918505Sralph continue; 10018505Sralph } 10124687Sbloom if (type != T_A) { 10218505Sralph if (_res.options & RES_DEBUG) 10318505Sralph printf("unexpected answer type %d, size %d\n", 10418505Sralph type, n); 10524687Sbloom cp += n; 10618505Sralph continue; 10718505Sralph } 10824687Sbloom if (haveanswer) { 10924687Sbloom if (n != host.h_length) { 11024687Sbloom cp += n; 11124687Sbloom continue; 11224687Sbloom } 11324687Sbloom if (class != getclass) { 11424687Sbloom cp += n; 11524687Sbloom continue; 11624687Sbloom } 11724687Sbloom } else { 11824687Sbloom host.h_length = n; 11924687Sbloom getclass = class; 12024687Sbloom host.h_addrtype = C_IN ? AF_INET : AF_UNSPEC; 12124687Sbloom if (!iquery) { 12224687Sbloom host.h_name = bp; 12324687Sbloom bp += strlen(bp) + 1; 12424687Sbloom } 12518505Sralph } 12618505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 12718505Sralph if (_res.options & RES_DEBUG) 12818505Sralph printf("size (%d) too big\n", n); 12924687Sbloom break; 13018505Sralph } 13124687Sbloom bcopy(cp, *hap++ = bp, n); 13224687Sbloom bp +=n; 13324687Sbloom cp += n; 13424687Sbloom haveanswer++; 13524687Sbloom } 13624687Sbloom if (haveanswer) { 13724687Sbloom *ap = NULL; 13824687Sbloom *hap = NULL; 13918505Sralph return (&host); 14024687Sbloom } else 14124687Sbloom return (NULL); 14215662Sralph } 14315662Sralph 14415662Sralph struct hostent * 14518505Sralph gethostbyname(name) 14618505Sralph char *name; 14715662Sralph { 14818505Sralph int n; 14924687Sbloom char buf[BUFSIZ+1]; 15015662Sralph 15124687Sbloom n = res_mkquery(QUERY, name, C_ANY, T_A, (char *)NULL, 0, NULL, 152*24713Sbloom buf, sizeof(buf)); 15318505Sralph if (n < 0) { 15418505Sralph if (_res.options & RES_DEBUG) 15518531Sralph printf("res_mkquery failed\n"); 15618505Sralph return (NULL); 15717761Sserge } 15824687Sbloom return(getanswer(buf, n, 0)); 15915662Sralph } 16015662Sralph 16115662Sralph struct hostent * 16218505Sralph gethostbyaddr(addr, len, type) 16315662Sralph char *addr; 16418505Sralph int len, type; 16515662Sralph { 16618505Sralph int n; 16724687Sbloom char buf[BUFSIZ+1]; 16815662Sralph 16918505Sralph if (type != AF_INET) 17018505Sralph return (NULL); 17124687Sbloom n = res_mkquery(IQUERY, (char *)NULL, C_IN, T_A, addr, len, NULL, 172*24713Sbloom buf, sizeof(buf)); 17318505Sralph if (n < 0) { 17418505Sralph if (_res.options & RES_DEBUG) 17518531Sralph printf("res_mkquery failed\n"); 17618505Sralph return (NULL); 17717761Sserge } 17824687Sbloom return(getanswer(buf, n, 1)); 17915662Sralph } 18024509Sbloom 18124509Sbloom 182