|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985, 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #if defined(LIBC_SCCS) && !defined(lint) ! 19: static char sccsid[] = "@(#)gethostnamadr.c 6.34 (Berkeley) 6/27/88"; ! 20: #endif /* LIBC_SCCS and not lint */ ! 21: ! 22: #include <sys/param.h> ! 23: #include <sys/socket.h> ! 24: #include <netinet/in.h> ! 25: #include <ctype.h> ! 26: #include <netdb.h> ! 27: #include <stdio.h> ! 28: #include <errno.h> ! 29: #include <arpa/inet.h> ! 30: #include <arpa/nameser.h> ! 31: #include <resolv.h> ! 32: ! 33: #define MAXALIASES 35 ! 34: #define MAXADDRS 35 ! 35: ! 36: static char *h_addr_ptrs[MAXADDRS + 1]; ! 37: ! 38: static struct hostent host; ! 39: static char *host_aliases[MAXALIASES]; ! 40: static char hostbuf[BUFSIZ+1]; ! 41: static struct in_addr host_addr; ! 42: static char HOSTDB[] = "/etc/hosts"; ! 43: static FILE *hostf = NULL; ! 44: static char hostaddr[MAXADDRS]; ! 45: static char *host_addrs[2]; ! 46: static int stayopen = 0; ! 47: static char *any(); ! 48: ! 49: #if PACKETSZ > 1024 ! 50: #define MAXPACKET PACKETSZ ! 51: #else ! 52: #define MAXPACKET 1024 ! 53: #endif ! 54: ! 55: typedef union { ! 56: HEADER hdr; ! 57: u_char buf[MAXPACKET]; ! 58: } querybuf; ! 59: ! 60: static union { ! 61: long al; ! 62: char ac; ! 63: } align; ! 64: ! 65: ! 66: int h_errno; ! 67: extern errno; ! 68: ! 69: static struct hostent * ! 70: getanswer(answer, anslen, iquery) ! 71: querybuf *answer; ! 72: int anslen; ! 73: int iquery; ! 74: { ! 75: register HEADER *hp; ! 76: register u_char *cp; ! 77: register int n; ! 78: u_char *eom; ! 79: char *bp, **ap; ! 80: int type, class, buflen, ancount, qdcount; ! 81: int haveanswer, getclass = C_ANY; ! 82: char **hap; ! 83: ! 84: eom = answer->buf + anslen; ! 85: /* ! 86: * find first satisfactory answer ! 87: */ ! 88: hp = &answer->hdr; ! 89: ancount = ntohs(hp->ancount); ! 90: qdcount = ntohs(hp->qdcount); ! 91: bp = hostbuf; ! 92: buflen = sizeof(hostbuf); ! 93: cp = answer->buf + sizeof(HEADER); ! 94: if (qdcount) { ! 95: if (iquery) { ! 96: if ((n = dn_expand((char *)answer->buf, eom, ! 97: cp, bp, buflen)) < 0) { ! 98: h_errno = NO_RECOVERY; ! 99: return ((struct hostent *) NULL); ! 100: } ! 101: cp += n + QFIXEDSZ; ! 102: host.h_name = bp; ! 103: n = strlen(bp) + 1; ! 104: bp += n; ! 105: buflen -= n; ! 106: } else ! 107: cp += dn_skipname(cp, eom) + QFIXEDSZ; ! 108: while (--qdcount > 0) ! 109: cp += dn_skipname(cp, eom) + QFIXEDSZ; ! 110: } else if (iquery) { ! 111: if (hp->aa) ! 112: h_errno = HOST_NOT_FOUND; ! 113: else ! 114: h_errno = TRY_AGAIN; ! 115: return ((struct hostent *) NULL); ! 116: } ! 117: ap = host_aliases; ! 118: host.h_aliases = host_aliases; ! 119: hap = h_addr_ptrs; ! 120: #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ ! 121: host.h_addr_list = h_addr_ptrs; ! 122: #endif ! 123: haveanswer = 0; ! 124: while (--ancount >= 0 && cp < eom) { ! 125: if ((n = dn_expand((char *)answer->buf, eom, cp, bp, buflen)) < 0) ! 126: break; ! 127: cp += n; ! 128: type = _getshort(cp); ! 129: cp += sizeof(u_short); ! 130: class = _getshort(cp); ! 131: cp += sizeof(u_short) + sizeof(u_long); ! 132: n = _getshort(cp); ! 133: cp += sizeof(u_short); ! 134: if (type == T_CNAME) { ! 135: cp += n; ! 136: if (ap >= &host_aliases[MAXALIASES-1]) ! 137: continue; ! 138: *ap++ = bp; ! 139: n = strlen(bp) + 1; ! 140: bp += n; ! 141: buflen -= n; ! 142: continue; ! 143: } ! 144: if (iquery && type == T_PTR) { ! 145: if ((n = dn_expand((char *)answer->buf, eom, ! 146: cp, bp, buflen)) < 0) { ! 147: cp += n; ! 148: continue; ! 149: } ! 150: cp += n; ! 151: host.h_name = bp; ! 152: return(&host); ! 153: } ! 154: if (iquery || type != T_A) { ! 155: #ifdef DEBUG ! 156: if (_res.options & RES_DEBUG) ! 157: printf("unexpected answer type %d, size %d\n", ! 158: type, n); ! 159: #endif ! 160: cp += n; ! 161: continue; ! 162: } ! 163: if (haveanswer) { ! 164: if (n != host.h_length) { ! 165: cp += n; ! 166: continue; ! 167: } ! 168: if (class != getclass) { ! 169: cp += n; ! 170: continue; ! 171: } ! 172: } else { ! 173: host.h_length = n; ! 174: getclass = class; ! 175: host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; ! 176: if (!iquery) { ! 177: host.h_name = bp; ! 178: bp += strlen(bp) + 1; ! 179: } ! 180: } ! 181: ! 182: bp += sizeof(align) - ((u_long)bp % sizeof(align)); ! 183: ! 184: if (bp + n >= &hostbuf[sizeof(hostbuf)]) { ! 185: #ifdef DEBUG ! 186: if (_res.options & RES_DEBUG) ! 187: printf("size (%d) too big\n", n); ! 188: #endif ! 189: break; ! 190: } ! 191: bcopy(cp, *hap++ = bp, n); ! 192: bp +=n; ! 193: cp += n; ! 194: haveanswer++; ! 195: } ! 196: if (haveanswer) { ! 197: *ap = NULL; ! 198: #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ ! 199: *hap = NULL; ! 200: #else ! 201: host.h_addr = h_addr_ptrs[0]; ! 202: #endif ! 203: return (&host); ! 204: } else { ! 205: h_errno = TRY_AGAIN; ! 206: return ((struct hostent *) NULL); ! 207: } ! 208: } ! 209: ! 210: struct hostent * ! 211: gethostbyname(name) ! 212: char *name; ! 213: { ! 214: querybuf buf; ! 215: register char *cp; ! 216: int n; ! 217: struct hostent *hp; ! 218: extern struct hostent *_gethtbyname(); ! 219: ! 220: /* ! 221: * disallow names consisting only of digits/dots, unless ! 222: * they end in a dot. ! 223: */ ! 224: if (isdigit(name[0])) ! 225: for (cp = name;; ++cp) { ! 226: if (!*cp) { ! 227: if (*--cp == '.') ! 228: break; ! 229: h_errno = HOST_NOT_FOUND; ! 230: return ((struct hostent *) NULL); ! 231: } ! 232: if (!isdigit(*cp) && *cp != '.') ! 233: break; ! 234: } ! 235: ! 236: if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) { ! 237: #ifdef DEBUG ! 238: if (_res.options & RES_DEBUG) ! 239: printf("res_search failed\n"); ! 240: #endif ! 241: if (errno == ECONNREFUSED) ! 242: return (_gethtbyname(name)); ! 243: else ! 244: return ((struct hostent *) NULL); ! 245: } ! 246: return (getanswer(&buf, n, 0)); ! 247: } ! 248: ! 249: struct hostent * ! 250: gethostbyaddr(addr, len, type) ! 251: char *addr; ! 252: int len, type; ! 253: { ! 254: int n; ! 255: querybuf buf; ! 256: register struct hostent *hp; ! 257: char qbuf[MAXDNAME]; ! 258: extern struct hostent *_gethtbyaddr(); ! 259: ! 260: if (type != AF_INET) ! 261: return ((struct hostent *) NULL); ! 262: (void)sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa", ! 263: ((unsigned)addr[3] & 0xff), ! 264: ((unsigned)addr[2] & 0xff), ! 265: ((unsigned)addr[1] & 0xff), ! 266: ((unsigned)addr[0] & 0xff)); ! 267: n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf)); ! 268: if (n < 0) { ! 269: #ifdef DEBUG ! 270: if (_res.options & RES_DEBUG) ! 271: printf("res_query failed\n"); ! 272: #endif ! 273: if (errno == ECONNREFUSED) ! 274: return (_gethtbyaddr(addr, len, type)); ! 275: return ((struct hostent *) NULL); ! 276: } ! 277: hp = getanswer(&buf, n, 1); ! 278: if (hp == NULL) ! 279: return ((struct hostent *) NULL); ! 280: hp->h_addrtype = type; ! 281: hp->h_length = len; ! 282: h_addr_ptrs[0] = (char *)&host_addr; ! 283: h_addr_ptrs[1] = (char *)0; ! 284: host_addr = *(struct in_addr *)addr; ! 285: return(hp); ! 286: } ! 287: ! 288: _sethtent(f) ! 289: int f; ! 290: { ! 291: if (hostf == NULL) ! 292: hostf = fopen(HOSTDB, "r" ); ! 293: else ! 294: rewind(hostf); ! 295: stayopen |= f; ! 296: } ! 297: ! 298: _endhtent() ! 299: { ! 300: if (hostf && !stayopen) { ! 301: (void) fclose(hostf); ! 302: hostf = NULL; ! 303: } ! 304: } ! 305: ! 306: struct hostent * ! 307: _gethtent() ! 308: { ! 309: char *p; ! 310: register char *cp, **q; ! 311: ! 312: if (hostf == NULL && (hostf = fopen(HOSTDB, "r" )) == NULL) ! 313: return (NULL); ! 314: again: ! 315: if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL) ! 316: return (NULL); ! 317: if (*p == '#') ! 318: goto again; ! 319: cp = any(p, "#\n"); ! 320: if (cp == NULL) ! 321: goto again; ! 322: *cp = '\0'; ! 323: cp = any(p, " \t"); ! 324: if (cp == NULL) ! 325: goto again; ! 326: *cp++ = '\0'; ! 327: /* THIS STUFF IS INTERNET SPECIFIC */ ! 328: #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ ! 329: host.h_addr_list = host_addrs; ! 330: #endif ! 331: host.h_addr = hostaddr; ! 332: *((u_long *)host.h_addr) = inet_addr(p); ! 333: host.h_length = sizeof (u_long); ! 334: host.h_addrtype = AF_INET; ! 335: while (*cp == ' ' || *cp == '\t') ! 336: cp++; ! 337: host.h_name = cp; ! 338: q = host.h_aliases = host_aliases; ! 339: cp = any(cp, " \t"); ! 340: if (cp != NULL) ! 341: *cp++ = '\0'; ! 342: while (cp && *cp) { ! 343: if (*cp == ' ' || *cp == '\t') { ! 344: cp++; ! 345: continue; ! 346: } ! 347: if (q < &host_aliases[MAXALIASES - 1]) ! 348: *q++ = cp; ! 349: cp = any(cp, " \t"); ! 350: if (cp != NULL) ! 351: *cp++ = '\0'; ! 352: } ! 353: *q = NULL; ! 354: return (&host); ! 355: } ! 356: ! 357: static char * ! 358: any(cp, match) ! 359: register char *cp; ! 360: char *match; ! 361: { ! 362: register char *mp, c; ! 363: ! 364: while (c = *cp) { ! 365: for (mp = match; *mp; mp++) ! 366: if (*mp == c) ! 367: return (cp); ! 368: cp++; ! 369: } ! 370: return ((char *)0); ! 371: } ! 372: ! 373: struct hostent * ! 374: _gethtbyname(name) ! 375: char *name; ! 376: { ! 377: register struct hostent *p; ! 378: register char **cp; ! 379: ! 380: _sethtent(0); ! 381: while (p = _gethtent()) { ! 382: if (strcasecmp(p->h_name, name) == 0) ! 383: break; ! 384: for (cp = p->h_aliases; *cp != 0; cp++) ! 385: if (strcasecmp(*cp, name) == 0) ! 386: goto found; ! 387: } ! 388: found: ! 389: _endhtent(); ! 390: return (p); ! 391: } ! 392: ! 393: struct hostent * ! 394: _gethtbyaddr(addr, len, type) ! 395: char *addr; ! 396: int len, type; ! 397: { ! 398: register struct hostent *p; ! 399: ! 400: _sethtent(0); ! 401: while (p = _gethtent()) ! 402: if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) ! 403: break; ! 404: _endhtent(); ! 405: return (p); ! 406: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.