121374Sdist /* 225302Skjd * Copyright (c) 1985 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*26066Skjd static char sccsid[] = "@(#)gethostnamadr.c 6.4 (Berkeley) 02/04/86"; 921374Sdist #endif not lint 1021374Sdist 1125386Skjd #include <sys/param.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 2925302Skjd typedef union { 3025302Skjd HEADER qb1; 3125302Skjd char qb2[PACKETSZ]; 3225302Skjd } querybuf; 3324509Sbloom 3425302Skjd static union { 3525302Skjd long al; 3625302Skjd char ac; 3725302Skjd } align; 3825302Skjd 3925302Skjd 4025484Skjd int h_errno; 4125484Skjd 4215662Sralph static struct hostent * 4318505Sralph getanswer(msg, msglen, iquery) 4418505Sralph char *msg; 4518505Sralph int msglen, iquery; 4615662Sralph { 4718505Sralph register HEADER *hp; 4818505Sralph register char *cp; 4918505Sralph register int n; 5025302Skjd querybuf answer; 5118505Sralph char *eom, *bp, **ap; 5225153Sbloom int type, class, ancount, qdcount, buflen; 5324687Sbloom int haveanswer, getclass; 5424687Sbloom char **hap; 5515662Sralph 5625302Skjd n = res_send(msg, msglen, (char *)&answer, sizeof(answer)); 5718505Sralph if (n < 0) { 5824733Sbloom #ifdef DEBUG 5918505Sralph if (_res.options & RES_DEBUG) 6018531Sralph printf("res_send failed\n"); 6124733Sbloom #endif 6225484Skjd h_errno = TRY_AGAIN; 6318505Sralph return (NULL); 6415662Sralph } 6525302Skjd eom = (char *)&answer + n; 6618505Sralph /* 6718505Sralph * find first satisfactory answer 6818505Sralph */ 6925302Skjd hp = (HEADER *) &answer; 7018505Sralph ancount = ntohs(hp->ancount); 7125153Sbloom qdcount = ntohs(hp->qdcount); 7218505Sralph if (hp->rcode != NOERROR || ancount == 0) { 7324733Sbloom #ifdef DEBUG 7418505Sralph if (_res.options & RES_DEBUG) 7518505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 7624733Sbloom #endif 7725484Skjd switch (hp->rcode) { 7825484Skjd case NXDOMAIN: 7925484Skjd /* Check if it's an authoritive answer */ 8025484Skjd if (hp->aa) 8125484Skjd h_errno = HOST_NOT_FOUND; 8225484Skjd else 8325484Skjd h_errno = TRY_AGAIN; 8425484Skjd break; 8525484Skjd case SERVFAIL: 8625484Skjd h_errno = TRY_AGAIN; 8725484Skjd break; 8825484Skjd case NOERROR: 8925484Skjd h_errno = NO_ADDRESS; 9025484Skjd break; 9125484Skjd case FORMERR: 9225484Skjd case NOTIMP: 9325484Skjd case REFUSED: 9425484Skjd h_errno = NO_RECOVERY; 9525484Skjd } 9618505Sralph return (NULL); 9718505Sralph } 9818505Sralph bp = hostbuf; 9918505Sralph buflen = sizeof(hostbuf); 10025302Skjd cp = (char *)&answer + sizeof(HEADER); 10125153Sbloom if (qdcount) { 10218505Sralph if (iquery) { 103*26066Skjd if ((n = dn_expand((char *)&answer, eom, 104*26066Skjd cp, bp, buflen)) < 0) { 10525484Skjd h_errno = NO_RECOVERY; 10618505Sralph return (NULL); 10725484Skjd } 10818505Sralph cp += n + QFIXEDSZ; 10918505Sralph host.h_name = bp; 11018505Sralph n = strlen(bp) + 1; 11118505Sralph bp += n; 11218505Sralph buflen -= n; 11318505Sralph } else 11418505Sralph cp += dn_skip(cp) + QFIXEDSZ; 11525153Sbloom while (--qdcount > 0) 11625153Sbloom cp += dn_skip(cp) + QFIXEDSZ; 11725484Skjd } else if (iquery) { 11825484Skjd if (hp->aa) 11925484Skjd h_errno = HOST_NOT_FOUND; 12025484Skjd else 12125484Skjd h_errno = TRY_AGAIN; 12218505Sralph return (NULL); 12325484Skjd } 12424687Sbloom ap = host_aliases; 12524687Sbloom host.h_aliases = host_aliases; 12624687Sbloom hap = h_addr_ptrs; 12724687Sbloom host.h_addr_list = h_addr_ptrs; 12824687Sbloom haveanswer = 0; 12918505Sralph while (--ancount >= 0 && cp < eom) { 130*26066Skjd if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0) 13124687Sbloom break; 13218505Sralph cp += n; 13318505Sralph type = getshort(cp); 13418505Sralph cp += sizeof(u_short); 13518505Sralph class = getshort(cp); 13618505Sralph cp += sizeof(u_short) + sizeof(u_long); 13718505Sralph n = getshort(cp); 13818505Sralph cp += sizeof(u_short); 13918505Sralph if (type == T_CNAME) { 14018505Sralph cp += n; 14118505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 14218505Sralph continue; 14318505Sralph *ap++ = bp; 14418505Sralph n = strlen(bp) + 1; 14518505Sralph bp += n; 14618505Sralph buflen -= n; 14718505Sralph continue; 14818505Sralph } 14925153Sbloom if (type == T_PTR) { 150*26066Skjd if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 15125302Skjd 0) { 15225153Sbloom cp += n; 15325153Sbloom continue; 15425153Sbloom } 15525153Sbloom cp += n; 15625153Sbloom host.h_name = bp; 15725153Sbloom return(&host); 15825153Sbloom } 15924687Sbloom if (type != T_A) { 16024733Sbloom #ifdef DEBUG 16118505Sralph if (_res.options & RES_DEBUG) 16218505Sralph printf("unexpected answer type %d, size %d\n", 16318505Sralph type, n); 16424733Sbloom #endif 16524687Sbloom cp += n; 16618505Sralph continue; 16718505Sralph } 16824687Sbloom if (haveanswer) { 16924687Sbloom if (n != host.h_length) { 17024687Sbloom cp += n; 17124687Sbloom continue; 17224687Sbloom } 17324687Sbloom if (class != getclass) { 17424687Sbloom cp += n; 17524687Sbloom continue; 17624687Sbloom } 17724687Sbloom } else { 17824687Sbloom host.h_length = n; 17924687Sbloom getclass = class; 18025386Skjd host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; 18124687Sbloom if (!iquery) { 18224687Sbloom host.h_name = bp; 18324687Sbloom bp += strlen(bp) + 1; 18424687Sbloom } 18518505Sralph } 18625302Skjd 18725302Skjd bp += ((u_long)bp % sizeof(align)); 18825302Skjd 18918505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 19024733Sbloom #ifdef DEBUG 19118505Sralph if (_res.options & RES_DEBUG) 19218505Sralph printf("size (%d) too big\n", n); 19324733Sbloom #endif 19424687Sbloom break; 19518505Sralph } 19624687Sbloom bcopy(cp, *hap++ = bp, n); 19724687Sbloom bp +=n; 19824687Sbloom cp += n; 19924687Sbloom haveanswer++; 20024687Sbloom } 20124687Sbloom if (haveanswer) { 20224687Sbloom *ap = NULL; 20324687Sbloom *hap = NULL; 20418505Sralph return (&host); 20525484Skjd } else { 20625484Skjd h_errno = TRY_AGAIN; 20724687Sbloom return (NULL); 20825484Skjd } 20915662Sralph } 21015662Sralph 21115662Sralph struct hostent * 21218505Sralph gethostbyname(name) 21318505Sralph char *name; 21415662Sralph { 21518505Sralph int n; 21625302Skjd querybuf buf; 21715662Sralph 21824687Sbloom n = res_mkquery(QUERY, name, C_ANY, T_A, (char *)NULL, 0, NULL, 21925302Skjd (char *)&buf, sizeof(buf)); 22018505Sralph if (n < 0) { 22124733Sbloom #ifdef DEBUG 22218505Sralph if (_res.options & RES_DEBUG) 22318531Sralph printf("res_mkquery failed\n"); 22424733Sbloom #endif 22518505Sralph return (NULL); 22617761Sserge } 22725302Skjd return(getanswer((char *)&buf, n, 0)); 22815662Sralph } 22915662Sralph 23015662Sralph struct hostent * 23118505Sralph gethostbyaddr(addr, len, type) 23215662Sralph char *addr; 23318505Sralph int len, type; 23415662Sralph { 23518505Sralph int n; 23625302Skjd querybuf buf; 23725153Sbloom register struct hostent *hp; 23825153Sbloom char qbuf[MAXDNAME]; 23915662Sralph 24018505Sralph if (type != AF_INET) 24118505Sralph return (NULL); 24225153Sbloom (void)sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa", 24325484Skjd ((unsigned)addr[3] & 0xff), 24425484Skjd ((unsigned)addr[2] & 0xff), 24525484Skjd ((unsigned)addr[1] & 0xff), 24625484Skjd ((unsigned)addr[0] & 0xff)); 24725153Sbloom n = res_mkquery(QUERY, qbuf, C_IN, T_PTR, NULL, 0, NULL, 24825302Skjd (char *)&buf, sizeof(buf)); 24918505Sralph if (n < 0) { 25024733Sbloom #ifdef DEBUG 25118505Sralph if (_res.options & RES_DEBUG) 25218531Sralph printf("res_mkquery failed\n"); 25324733Sbloom #endif 25418505Sralph return (NULL); 25517761Sserge } 25625302Skjd if ((hp = getanswer((char *)&buf, n, 1)) == NULL) 25725153Sbloom return(NULL); 25825153Sbloom hp->h_addrtype = type; 25925153Sbloom hp->h_length = len; 26025282Sbloom h_addr_ptrs[0] = (char *)&host_addr; 26125153Sbloom h_addr_ptrs[1] = (char *)0; 26225153Sbloom host_addr = *(struct in_addr *)addr; 26325153Sbloom return(hp); 26415662Sralph } 26525302Skjd 266