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*25386Skjd static char sccsid[] = "@(#)gethostnamadr.c 6.2 (Berkeley) 11/04/85"; 921374Sdist #endif not lint 1021374Sdist 1118505Sralph #include <sys/types.h> 12*25386Skjd #include <sys/param.h> 1318505Sralph #include <sys/socket.h> 1418505Sralph #include <netinet/in.h> 1518505Sralph #include <netdb.h> 1615662Sralph #include <stdio.h> 1724508Sbloom #include <arpa/nameser.h> 1824508Sbloom #include <arpa/resolv.h> 1915662Sralph 2015662Sralph #define MAXALIASES 35 2124687Sbloom #define MAXADDRS 35 2215662Sralph 2324687Sbloom static char *h_addr_ptrs[MAXADDRS + 1]; 2424687Sbloom 2524687Sbloom static struct hostent host; 2615662Sralph static char *host_aliases[MAXALIASES]; 2715912Sralph static char hostbuf[BUFSIZ+1]; 2825153Sbloom static struct in_addr host_addr; 2915662Sralph 3025302Skjd typedef union { 3125302Skjd HEADER qb1; 3225302Skjd char qb2[PACKETSZ]; 3325302Skjd } querybuf; 3424509Sbloom 3525302Skjd static union { 3625302Skjd long al; 3725302Skjd char ac; 3825302Skjd } align; 3925302Skjd 4025302Skjd 4115662Sralph static struct hostent * 4218505Sralph getanswer(msg, msglen, iquery) 4318505Sralph char *msg; 4418505Sralph int msglen, iquery; 4515662Sralph { 4618505Sralph register HEADER *hp; 4718505Sralph register char *cp; 4818505Sralph register int n; 4925302Skjd querybuf answer; 5018505Sralph char *eom, *bp, **ap; 5125153Sbloom int type, class, ancount, qdcount, buflen; 5224687Sbloom int haveanswer, getclass; 5324687Sbloom char **hap; 5415662Sralph 5525302Skjd n = res_send(msg, msglen, (char *)&answer, sizeof(answer)); 5618505Sralph if (n < 0) { 5724733Sbloom #ifdef DEBUG 5818505Sralph if (_res.options & RES_DEBUG) 5918531Sralph printf("res_send failed\n"); 6024733Sbloom #endif 6118505Sralph return (NULL); 6215662Sralph } 6325302Skjd eom = (char *)&answer + n; 6418505Sralph /* 6518505Sralph * find first satisfactory answer 6618505Sralph */ 6725302Skjd hp = (HEADER *) &answer; 6818505Sralph ancount = ntohs(hp->ancount); 6925153Sbloom qdcount = ntohs(hp->qdcount); 7018505Sralph if (hp->rcode != NOERROR || ancount == 0) { 7124733Sbloom #ifdef DEBUG 7218505Sralph if (_res.options & RES_DEBUG) 7318505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 7424733Sbloom #endif 7518505Sralph return (NULL); 7618505Sralph } 7718505Sralph bp = hostbuf; 7818505Sralph buflen = sizeof(hostbuf); 7925302Skjd cp = (char *)&answer + sizeof(HEADER); 8025153Sbloom if (qdcount) { 8118505Sralph if (iquery) { 82*25386Skjd if ((n = dn_expand((char *)&answer, cp, bp, buflen)) <0) 8318505Sralph return (NULL); 8418505Sralph cp += n + QFIXEDSZ; 8518505Sralph host.h_name = bp; 8618505Sralph n = strlen(bp) + 1; 8718505Sralph bp += n; 8818505Sralph buflen -= n; 8918505Sralph } else 9018505Sralph cp += dn_skip(cp) + QFIXEDSZ; 9125153Sbloom while (--qdcount > 0) 9225153Sbloom cp += dn_skip(cp) + QFIXEDSZ; 9318505Sralph } else if (iquery) 9418505Sralph return (NULL); 9524687Sbloom ap = host_aliases; 9624687Sbloom host.h_aliases = host_aliases; 9724687Sbloom hap = h_addr_ptrs; 98*25386Skjd #ifdef BSD4_3 9924687Sbloom host.h_addr_list = h_addr_ptrs; 100*25386Skjd #endif 10124687Sbloom haveanswer = 0; 10218505Sralph while (--ancount >= 0 && cp < eom) { 10325302Skjd if ((n = dn_expand((char *)&answer, cp, bp, buflen)) < 0) 10424687Sbloom break; 10518505Sralph cp += n; 10618505Sralph type = getshort(cp); 10718505Sralph cp += sizeof(u_short); 10818505Sralph class = getshort(cp); 10918505Sralph cp += sizeof(u_short) + sizeof(u_long); 11018505Sralph n = getshort(cp); 11118505Sralph cp += sizeof(u_short); 11218505Sralph if (type == T_CNAME) { 11318505Sralph cp += n; 11418505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 11518505Sralph continue; 11618505Sralph *ap++ = bp; 11718505Sralph n = strlen(bp) + 1; 11818505Sralph bp += n; 11918505Sralph buflen -= n; 12018505Sralph continue; 12118505Sralph } 12225153Sbloom if (type == T_PTR) { 12325302Skjd if ((n = dn_expand((char *)&answer, cp, bp, buflen)) < 12425302Skjd 0) { 12525153Sbloom cp += n; 12625153Sbloom continue; 12725153Sbloom } 12825153Sbloom cp += n; 12925153Sbloom host.h_name = bp; 130*25386Skjd #ifdef BSD4_3 13125153Sbloom return(&host); 132*25386Skjd #else 133*25386Skjd haveanswer++; 134*25386Skjd break; 135*25386Skjd #endif 13625153Sbloom } 13724687Sbloom if (type != T_A) { 13824733Sbloom #ifdef DEBUG 13918505Sralph if (_res.options & RES_DEBUG) 14018505Sralph printf("unexpected answer type %d, size %d\n", 14118505Sralph type, n); 14224733Sbloom #endif 14324687Sbloom cp += n; 14418505Sralph continue; 14518505Sralph } 14624687Sbloom if (haveanswer) { 14724687Sbloom if (n != host.h_length) { 14824687Sbloom cp += n; 14924687Sbloom continue; 15024687Sbloom } 15124687Sbloom if (class != getclass) { 15224687Sbloom cp += n; 15324687Sbloom continue; 15424687Sbloom } 15524687Sbloom } else { 15624687Sbloom host.h_length = n; 15724687Sbloom getclass = class; 158*25386Skjd host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; 15924687Sbloom if (!iquery) { 16024687Sbloom host.h_name = bp; 16124687Sbloom bp += strlen(bp) + 1; 16224687Sbloom } 16318505Sralph } 16425302Skjd 16525302Skjd bp += ((u_long)bp % sizeof(align)); 16625302Skjd 16718505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 16824733Sbloom #ifdef DEBUG 16918505Sralph if (_res.options & RES_DEBUG) 17018505Sralph printf("size (%d) too big\n", n); 17124733Sbloom #endif 17224687Sbloom break; 17318505Sralph } 17424687Sbloom bcopy(cp, *hap++ = bp, n); 17524687Sbloom bp +=n; 17624687Sbloom cp += n; 17724687Sbloom haveanswer++; 17824687Sbloom } 17924687Sbloom if (haveanswer) { 18024687Sbloom *ap = NULL; 18124687Sbloom *hap = NULL; 182*25386Skjd #ifndef BSD4_3 183*25386Skjd host.h_addr = h_addr_ptrs[0]; 184*25386Skjd #endif 18518505Sralph return (&host); 18624687Sbloom } else 18724687Sbloom return (NULL); 18815662Sralph } 18915662Sralph 19015662Sralph struct hostent * 19118505Sralph gethostbyname(name) 19218505Sralph char *name; 19315662Sralph { 19418505Sralph int n; 19525302Skjd querybuf buf; 19615662Sralph 19724687Sbloom n = res_mkquery(QUERY, name, C_ANY, T_A, (char *)NULL, 0, NULL, 19825302Skjd (char *)&buf, sizeof(buf)); 19918505Sralph if (n < 0) { 20024733Sbloom #ifdef DEBUG 20118505Sralph if (_res.options & RES_DEBUG) 20218531Sralph printf("res_mkquery failed\n"); 20324733Sbloom #endif 20418505Sralph return (NULL); 20517761Sserge } 20625302Skjd return(getanswer((char *)&buf, n, 0)); 20715662Sralph } 20815662Sralph 20915662Sralph struct hostent * 21018505Sralph gethostbyaddr(addr, len, type) 21115662Sralph char *addr; 21218505Sralph int len, type; 21315662Sralph { 21418505Sralph int n; 21525302Skjd querybuf buf; 21625153Sbloom register struct hostent *hp; 21725153Sbloom char qbuf[MAXDNAME]; 21815662Sralph 21918505Sralph if (type != AF_INET) 22018505Sralph return (NULL); 22125153Sbloom (void)sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa", 22225153Sbloom (*(unsigned *)addr >> 24 & 0xff), 22325153Sbloom (*(unsigned *)addr >> 16 & 0xff), 22425153Sbloom (*(unsigned *)addr >> 8 & 0xff), 22525153Sbloom (*(unsigned *)addr & 0xff)); 22625153Sbloom n = res_mkquery(QUERY, qbuf, C_IN, T_PTR, NULL, 0, NULL, 22725302Skjd (char *)&buf, sizeof(buf)); 22818505Sralph if (n < 0) { 22924733Sbloom #ifdef DEBUG 23018505Sralph if (_res.options & RES_DEBUG) 23118531Sralph printf("res_mkquery failed\n"); 23224733Sbloom #endif 23318505Sralph return (NULL); 23417761Sserge } 23525302Skjd if ((hp = getanswer((char *)&buf, n, 1)) == NULL) 23625153Sbloom return(NULL); 23725153Sbloom hp->h_addrtype = type; 23825153Sbloom hp->h_length = len; 23925282Sbloom h_addr_ptrs[0] = (char *)&host_addr; 24025153Sbloom h_addr_ptrs[1] = (char *)0; 24125153Sbloom host_addr = *(struct in_addr *)addr; 24225153Sbloom return(hp); 24315662Sralph } 24425302Skjd 245