121374Sdist /* 2*24509Sbloom * 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*24509Sbloom static char sccsid[] = "@(#)gethostnamadr.c 5.3 (Berkeley) 09/03/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 2015662Sralph 21*24509Sbloom #define XX 2 22*24509Sbloom static char h_addr_buf[sizeof(struct in_addr) * XX]; 23*24509Sbloom static char *h_addr_ptr[XX] = { 24*24509Sbloom &h_addr_buf[0], 25*24509Sbloom &h_addr_buf[sizeof(struct in_addr)] 26*24509Sbloom }; 27*24509Sbloom static struct hostent host = { 28*24509Sbloom NULL, /* official name of host */ 29*24509Sbloom NULL, /* alias list */ 30*24509Sbloom 0, /* host address type */ 31*24509Sbloom 0, /* length of address */ 32*24509Sbloom h_addr_ptr /* list of addresses from name server */ 33*24509Sbloom }; 3415662Sralph static char *host_aliases[MAXALIASES]; 3515912Sralph static char hostbuf[BUFSIZ+1]; 3615662Sralph 37*24509Sbloom #ifdef BOMBPROOFING 38*24509Sbloom #include <ndbm.h> 39*24509Sbloom DBM *_host_db = NULL; 40*24509Sbloom int _host_stayopen = 0; 41*24509Sbloom int _host_bombed; 42*24509Sbloom struct hostent *_oldgethostbyname(), *_oldgethostbyaddr(); 43*24509Sbloom #endif BOMBPROOFING 44*24509Sbloom 4515662Sralph static struct hostent * 4618505Sralph getanswer(msg, msglen, iquery) 4718505Sralph char *msg; 4818505Sralph int msglen, iquery; 4915662Sralph { 5018505Sralph register HEADER *hp; 5118505Sralph register char *cp; 5218505Sralph register int n; 5318505Sralph char answer[PACKETSZ]; 5418505Sralph char *eom, *bp, **ap; 5518505Sralph int type, class, ancount, buflen; 5615662Sralph 57*24509Sbloom #ifdef BOMBPROOFING 58*24509Sbloom _host_bombed = 0; 59*24509Sbloom #endif BOMBPROOFING 6018531Sralph n = res_send(msg, msglen, answer, sizeof(answer)); 6118505Sralph if (n < 0) { 6218505Sralph if (_res.options & RES_DEBUG) 6318531Sralph printf("res_send failed\n"); 64*24509Sbloom #ifdef BOMBPROOFING 65*24509Sbloom _host_bombed++; 66*24509Sbloom #endif BOMBPROOFING 6718505Sralph return (NULL); 6815662Sralph } 6918505Sralph eom = answer + n; 7018505Sralph /* 7118505Sralph * find first satisfactory answer 7218505Sralph */ 7318505Sralph hp = (HEADER *) answer; 7418505Sralph ancount = ntohs(hp->ancount); 7518505Sralph if (hp->rcode != NOERROR || ancount == 0) { 7618505Sralph if (_res.options & RES_DEBUG) 7718505Sralph printf("rcode = %d, ancount=%d\n", hp->rcode, ancount); 78*24509Sbloom #ifdef BOMBPROOFING 79*24509Sbloom if (!(hp->rcode == NOERROR && ancount == 0)) 80*24509Sbloom _host_bombed++; 81*24509Sbloom #endif BOMBPROOFING 8218505Sralph return (NULL); 8318505Sralph } 8418505Sralph bp = hostbuf; 8518505Sralph buflen = sizeof(hostbuf); 8618505Sralph ap = host_aliases; 8718505Sralph cp = answer + sizeof(HEADER); 8818505Sralph if (hp->qdcount) { 8918505Sralph if (iquery) { 9018505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 9118505Sralph return (NULL); 9218505Sralph cp += n + QFIXEDSZ; 9318505Sralph host.h_name = bp; 9418505Sralph n = strlen(bp) + 1; 9518505Sralph bp += n; 9618505Sralph buflen -= n; 9718505Sralph } else 9818505Sralph cp += dn_skip(cp) + QFIXEDSZ; 9918505Sralph } else if (iquery) 10018505Sralph return (NULL); 10118505Sralph while (--ancount >= 0 && cp < eom) { 10218505Sralph if ((n = dn_expand(answer, cp, bp, buflen)) < 0) 10318505Sralph return (NULL); 10418505Sralph cp += n; 10518505Sralph type = getshort(cp); 10618505Sralph cp += sizeof(u_short); 10718505Sralph class = getshort(cp); 10818505Sralph cp += sizeof(u_short) + sizeof(u_long); 10918505Sralph n = getshort(cp); 11018505Sralph cp += sizeof(u_short); 11118505Sralph if (type == T_CNAME) { 11218505Sralph cp += n; 11318505Sralph if (ap >= &host_aliases[MAXALIASES-1]) 11418505Sralph continue; 11518505Sralph *ap++ = bp; 11618505Sralph n = strlen(bp) + 1; 11718505Sralph bp += n; 11818505Sralph buflen -= n; 11918505Sralph continue; 12018505Sralph } 12118505Sralph if (type != T_A || n != 4) { 12218505Sralph if (_res.options & RES_DEBUG) 12318505Sralph printf("unexpected answer type %d, size %d\n", 12418505Sralph type, n); 12518505Sralph continue; 12618505Sralph } 12718505Sralph if (!iquery) { 12818505Sralph host.h_name = bp; 12918505Sralph bp += strlen(bp) + 1; 13018505Sralph } 13118505Sralph *ap = NULL; 13218505Sralph host.h_aliases = host_aliases; 13318505Sralph host.h_addrtype = class == C_IN ? AF_INET : AF_UNSPEC; 13418505Sralph if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 13518505Sralph if (_res.options & RES_DEBUG) 13618505Sralph printf("size (%d) too big\n", n); 13718505Sralph return (NULL); 13818505Sralph } 13918505Sralph bcopy(cp, host.h_addr = bp, host.h_length = n); 14018505Sralph return (&host); 14118505Sralph } 14218505Sralph return (NULL); 14315662Sralph } 14415662Sralph 14515662Sralph struct hostent * 14618505Sralph gethostbyname(name) 14718505Sralph char *name; 14815662Sralph { 14918505Sralph int n; 150*24509Sbloom #ifdef BOMBPROOFING 151*24509Sbloom register struct hostent *hp; 152*24509Sbloom #endif BOMBPROOFING 15315662Sralph 15418531Sralph n = res_mkquery(QUERY, name, C_ANY, T_A, NULL, 0, NULL, 15518531Sralph hostbuf, sizeof(hostbuf)); 15618505Sralph if (n < 0) { 15718505Sralph if (_res.options & RES_DEBUG) 15818531Sralph printf("res_mkquery failed\n"); 15918505Sralph return (NULL); 160*24509Sbloom #ifndef BOMBPROOFING 16117761Sserge } 162*24509Sbloom return(getanswer(hostbuf, n, 0)); 163*24509Sbloom #else 164*24509Sbloom } else 165*24509Sbloom hp = getanswer(hostbuf, n, 0); 166*24509Sbloom if (n < 0 || (hp == NULL && _host_bombed)) 167*24509Sbloom return (_oldgethostbyname(name)); 168*24509Sbloom else 169*24509Sbloom return (hp); 170*24509Sbloom #endif BOMBPROOFING 17115662Sralph } 17215662Sralph 17315662Sralph struct hostent * 17418505Sralph gethostbyaddr(addr, len, type) 17515662Sralph char *addr; 17618505Sralph int len, type; 17715662Sralph { 17818505Sralph int n; 179*24509Sbloom #ifdef BOMBPROOFING 180*24509Sbloom register struct hostent *hp; 181*24509Sbloom #endif BOMBPROOFING 18215662Sralph 18318505Sralph if (type != AF_INET) 18418505Sralph return (NULL); 18518531Sralph n = res_mkquery(IQUERY, NULL, C_IN, T_A, addr, len, NULL, 18618531Sralph hostbuf, sizeof(hostbuf)); 18718505Sralph if (n < 0) { 18818505Sralph if (_res.options & RES_DEBUG) 18918531Sralph printf("res_mkquery failed\n"); 19018505Sralph return (NULL); 191*24509Sbloom #ifndef BOMBPROOFING 19217761Sserge } 19318505Sralph return (getanswer(hostbuf, n, 1)); 194*24509Sbloom #else 195*24509Sbloom } else 196*24509Sbloom hp = getanswer(hostbuf, n, 1); 197*24509Sbloom if (n < 0 || (hp == NULL && _host_bombed)) 198*24509Sbloom return (_oldgethostbyaddr(addr)); 199*24509Sbloom else 200*24509Sbloom return (hp); 201*24509Sbloom #endif BOMBPROOFING 20215662Sralph } 203*24509Sbloom 204*24509Sbloom #ifdef BOMBPROOFING 205*24509Sbloom static 206*24509Sbloom struct hostent * 207*24509Sbloom _oldgethostbyname(name) 208*24509Sbloom register char *name; 209*24509Sbloom { 210*24509Sbloom register struct hostent *hp; 211*24509Sbloom register char **cp; 212*24509Sbloom datum key; 213*24509Sbloom 214*24509Sbloom if ((_host_db == (DBM *)NULL) 215*24509Sbloom && ((_host_db = dbm_open(_host_file, O_RDONLY)) == (DBM *)NULL)) { 216*24509Sbloom sethostent(_host_stayopen); 217*24509Sbloom while (hp = gethostent()) { 218*24509Sbloom if (strcmp(hp->h_name, nam) == 0) 219*24509Sbloom break; 220*24509Sbloom for (cp = hp->h_aliases; cp != 0 && *cp != 0; cp++) 221*24509Sbloom if (strcmp(*cp, nam) == 0) 222*24509Sbloom goto found; 223*24509Sbloom } 224*24509Sbloom found: 225*24509Sbloom if (!_host_stayopen) 226*24509Sbloom endhostent(); 227*24509Sbloom return (hp); 228*24509Sbloom } 229*24509Sbloom key.dptr = nam; 230*24509Sbloom key.dsize = strlen(nam); 231*24509Sbloom hp = fetchhost(key); 232*24509Sbloom if (!_host_stayopen) { 233*24509Sbloom dbm_close(_host_db); 234*24509Sbloom _host_db = (DBM *)NULL; 235*24509Sbloom } 236*24509Sbloom return (hp); 237*24509Sbloom } 238*24509Sbloom 239*24509Sbloom 240*24509Sbloom static 241*24509Sbloom struct hostent * 242*24509Sbloom _oldgethostbyaddr(addr, len, type) 243*24509Sbloom char *addr; 244*24509Sbloom register int len, type; 245*24509Sbloom { 246*24509Sbloom 247*24509Sbloom register struct hostent *hp; 248*24509Sbloom datum key; 249*24509Sbloom 250*24509Sbloom if ((_host_db == (DBM *)NULL) 251*24509Sbloom && ((_host_db = dbm_open(_host_file, O_RDONLY)) == (DBM *)NULL)) { 252*24509Sbloom sethostent(_host_stayopen); 253*24509Sbloom while (hp = gethostent()) { 254*24509Sbloom if (hp->h_addrtype == type && hp->h_length == length 255*24509Sbloom && bcmp(hp->h_addr, addr, length) == 0) 256*24509Sbloom break; 257*24509Sbloom } 258*24509Sbloom if (!_host_stayopen) 259*24509Sbloom endhostent(); 260*24509Sbloom return (hp); 261*24509Sbloom } 262*24509Sbloom key.dptr = addr; 263*24509Sbloom key.dsize = length; 264*24509Sbloom hp = fetchhost(key); 265*24509Sbloom if (!_host_stayopen) { 266*24509Sbloom dbm_close(_host_db); 267*24509Sbloom _host_db = (DBM *)NULL; 268*24509Sbloom } 269*24509Sbloom return (hp); 270*24509Sbloom } 271*24509Sbloom #endif BOMBPROOFING 272*24509Sbloom 273