121374Sdist /* 2*25302Skjd * 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*25302Skjd static char sccsid[] = "@(#)gethostnamadr.c 5.10 (Berkeley) 10/25/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 29*25302Skjd typedef union { 30*25302Skjd HEADER qb1; 31*25302Skjd char qb2[PACKETSZ]; 32*25302Skjd } querybuf; 3324509Sbloom 34*25302Skjd static union { 35*25302Skjd long al; 36*25302Skjd char ac; 37*25302Skjd } align; 38*25302Skjd 39*25302Skjd 4015662Sralph static struct hostent * 4118505Sralph getanswer(msg, msglen, iquery) 4218505Sralph char *msg; 4318505Sralph int msglen, iquery; 4415662Sralph { 4518505Sralph register HEADER *hp; 4618505Sralph register char *cp; 4718505Sralph register int n; 48*25302Skjd querybuf answer; 4918505Sralph char *eom, *bp, **ap; 5025153Sbloom int type, class, ancount, qdcount, buflen; 5124687Sbloom int haveanswer, getclass; 5224687Sbloom char **hap; 5315662Sralph 54*25302Skjd n = res_send(msg, msglen, (char *)&answer, sizeof(answer)); 5518505Sralph if (n < 0) { 5624733Sbloom #ifdef DEBUG 5718505Sralph if (_res.options & RES_DEBUG) 5818531Sralph printf("res_send failed\n"); 5924733Sbloom #endif 6018505Sralph return (NULL); 6115662Sralph } 62*25302Skjd eom = (char *)&answer + n; 6318505Sralph /* 6418505Sralph * find first satisfactory answer 6518505Sralph */ 66*25302Skjd hp = (HEADER *) &answer; 6718505Sralph ancount = ntohs(hp->ancount); 6825153Sbloom qdcount = ntohs(hp->qdcount); 6918505Sralph if (hp->rcode != NOERROR || ancount == 0) { 7024733Sbloom #ifdef DEBUG 7118505Sralph if (_res.options & RES_DEBUG) 7218505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 7324733Sbloom #endif 7418505Sralph return (NULL); 7518505Sralph } 7618505Sralph bp = hostbuf; 7718505Sralph buflen = sizeof(hostbuf); 78*25302Skjd cp = (char *)&answer + sizeof(HEADER); 7925153Sbloom if (qdcount) { 8018505Sralph if (iquery) { 81*25302Skjd if ((n = dn_expand((char *)&answer, cp, bp, buflen)) < 82*25302Skjd 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; 9824687Sbloom host.h_addr_list = h_addr_ptrs; 9924687Sbloom haveanswer = 0; 10018505Sralph while (--ancount >= 0 && cp < eom) { 101*25302Skjd if ((n = dn_expand((char *)&answer, cp, bp, buflen)) < 0) 10224687Sbloom break; 10318505Sralph cp += n; 10418505Sralph type = getshort(cp); 10518505Sralph cp += sizeof(u_short); 10618505Sralph class = getshort(cp); 10718505Sralph cp += sizeof(u_short) + sizeof(u_long); 10818505Sralph n = getshort(cp); 10918505Sralph cp += sizeof(u_short); 11018505Sralph if (type == T_CNAME) { 11118505Sralph cp += n; 11218505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 11318505Sralph continue; 11418505Sralph *ap++ = bp; 11518505Sralph n = strlen(bp) + 1; 11618505Sralph bp += n; 11718505Sralph buflen -= n; 11818505Sralph continue; 11918505Sralph } 12025153Sbloom if (type == T_PTR) { 121*25302Skjd if ((n = dn_expand((char *)&answer, cp, bp, buflen)) < 122*25302Skjd 0) { 12325153Sbloom cp += n; 12425153Sbloom continue; 12525153Sbloom } 12625153Sbloom cp += n; 12725153Sbloom host.h_name = bp; 12825153Sbloom return(&host); 12925153Sbloom } 13024687Sbloom if (type != T_A) { 13124733Sbloom #ifdef DEBUG 13218505Sralph if (_res.options & RES_DEBUG) 13318505Sralph printf("unexpected answer type %d, size %d\n", 13418505Sralph type, n); 13524733Sbloom #endif 13624687Sbloom cp += n; 13718505Sralph continue; 13818505Sralph } 13924687Sbloom if (haveanswer) { 14024687Sbloom if (n != host.h_length) { 14124687Sbloom cp += n; 14224687Sbloom continue; 14324687Sbloom } 14424687Sbloom if (class != getclass) { 14524687Sbloom cp += n; 14624687Sbloom continue; 14724687Sbloom } 14824687Sbloom } else { 14924687Sbloom host.h_length = n; 15024687Sbloom getclass = class; 15124687Sbloom host.h_addrtype = C_IN ? AF_INET : AF_UNSPEC; 15224687Sbloom if (!iquery) { 15324687Sbloom host.h_name = bp; 15424687Sbloom bp += strlen(bp) + 1; 15524687Sbloom } 15618505Sralph } 157*25302Skjd 158*25302Skjd bp += ((u_long)bp % sizeof(align)); 159*25302Skjd 16018505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 16124733Sbloom #ifdef DEBUG 16218505Sralph if (_res.options & RES_DEBUG) 16318505Sralph printf("size (%d) too big\n", n); 16424733Sbloom #endif 16524687Sbloom break; 16618505Sralph } 16724687Sbloom bcopy(cp, *hap++ = bp, n); 16824687Sbloom bp +=n; 16924687Sbloom cp += n; 17024687Sbloom haveanswer++; 17124687Sbloom } 17224687Sbloom if (haveanswer) { 17324687Sbloom *ap = NULL; 17424687Sbloom *hap = NULL; 17518505Sralph return (&host); 17624687Sbloom } else 17724687Sbloom return (NULL); 17815662Sralph } 17915662Sralph 18015662Sralph struct hostent * 18118505Sralph gethostbyname(name) 18218505Sralph char *name; 18315662Sralph { 18418505Sralph int n; 185*25302Skjd querybuf buf; 18615662Sralph 18724687Sbloom n = res_mkquery(QUERY, name, C_ANY, T_A, (char *)NULL, 0, NULL, 188*25302Skjd (char *)&buf, sizeof(buf)); 18918505Sralph if (n < 0) { 19024733Sbloom #ifdef DEBUG 19118505Sralph if (_res.options & RES_DEBUG) 19218531Sralph printf("res_mkquery failed\n"); 19324733Sbloom #endif 19418505Sralph return (NULL); 19517761Sserge } 196*25302Skjd return(getanswer((char *)&buf, n, 0)); 19715662Sralph } 19815662Sralph 19915662Sralph struct hostent * 20018505Sralph gethostbyaddr(addr, len, type) 20115662Sralph char *addr; 20218505Sralph int len, type; 20315662Sralph { 20418505Sralph int n; 205*25302Skjd querybuf buf; 20625153Sbloom register struct hostent *hp; 20725153Sbloom char qbuf[MAXDNAME]; 20815662Sralph 20918505Sralph if (type != AF_INET) 21018505Sralph return (NULL); 21125153Sbloom (void)sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa", 21225153Sbloom (*(unsigned *)addr >> 24 & 0xff), 21325153Sbloom (*(unsigned *)addr >> 16 & 0xff), 21425153Sbloom (*(unsigned *)addr >> 8 & 0xff), 21525153Sbloom (*(unsigned *)addr & 0xff)); 21625153Sbloom n = res_mkquery(QUERY, qbuf, C_IN, T_PTR, NULL, 0, NULL, 217*25302Skjd (char *)&buf, sizeof(buf)); 21818505Sralph if (n < 0) { 21924733Sbloom #ifdef DEBUG 22018505Sralph if (_res.options & RES_DEBUG) 22118531Sralph printf("res_mkquery failed\n"); 22224733Sbloom #endif 22318505Sralph return (NULL); 22417761Sserge } 225*25302Skjd if ((hp = getanswer((char *)&buf, n, 1)) == NULL) 22625153Sbloom return(NULL); 22725153Sbloom hp->h_addrtype = type; 22825153Sbloom hp->h_length = len; 22925282Sbloom h_addr_ptrs[0] = (char *)&host_addr; 23025153Sbloom h_addr_ptrs[1] = (char *)0; 23125153Sbloom host_addr = *(struct in_addr *)addr; 23225153Sbloom return(hp); 23315662Sralph } 234*25302Skjd 235