📄 gethostbydns.c
字号:
continue; } bcopy(cp, *hap++ = bp, n); bp += n; buflen -= n; cp += n; if (cp != erdata) { *herr = NO_RECOVERY; return (NULL); } break; default: dbgprintf("Impossible condition (type=%d)\n", type); *herr = NO_RECOVERY; return (NULL); /* BIND has abort() here, too risky on bad data */ } if (!had_error) haveanswer++; } if (haveanswer) { *ap = NULL; *hap = NULL;# if defined(RESOLVSORT) /* * Note: we sort even if host can take only one address * in its return structures - should give it the "best" * address in that case, not some random one */ if (_res.nsort && haveanswer > 1 && qtype == T_A) addrsort(host->__host_addrs, haveanswer);# endif /*RESOLVSORT*/ if (!host->h_name) { n = strlen(qname) + 1; /* for the \0 */ if (n > buflen || n >= MAXHOSTNAMELEN) goto no_recovery; strcpy(bp, qname); host->h_name = bp; bp += n; buflen -= n; } if (_res.options & RES_USE_INET6) _map_v4v6_hostent(host, &bp, &buflen); *herr = NETDB_SUCCESS; return host; } no_recovery: *herr = NO_RECOVERY; return (NULL);}struct hostent *__dns_getanswer(answer, anslen, qname, qtype, host, hostbuf, hostbuflen, herr) const char *answer; int anslen; const char *qname; int qtype; struct hostent *host; char *hostbuf; int hostbuflen; int *herr;{ switch(qtype) { case T_AAAA: host->h_addrtype = AF_INET6; host->h_length = IN6ADDRSZ; break; case T_A: default: host->h_addrtype = AF_INET; host->h_length = INADDRSZ; break; } return(gethostanswer((const querybuf *)answer, anslen, qname, qtype, host, hostbuf, hostbuflen, herr));}int_dns_gethostbyname(void *rval, void *cb_data, va_list ap){ const char *name; int af; querybuf buf; const char *cp; char *bp; int n, size, type, len; struct hostent *resultbuf; char *hostbuf; int buflen; int *herr; name = va_arg(ap, const char *); af = va_arg(ap, int); resultbuf = va_arg(ap, struct hostent *); hostbuf = va_arg(ap, char *); buflen = va_arg(ap, int); herr = va_arg(ap, int *); if ((_res.options & RES_INIT) == 0 && res_init() == -1) { *herr = NETDB_INTERNAL; return NS_UNAVAIL; } switch (af) { case AF_INET: size = INADDRSZ; type = T_A; break; case AF_INET6: size = IN6ADDRSZ; type = T_AAAA; break; default: *herr = NETDB_INTERNAL; errno = EAFNOSUPPORT; return NS_UNAVAIL; } resultbuf->h_addrtype = af; resultbuf->h_length = size; /* * if there aren't any dots, it could be a user-level alias. * this is also done in res_query() since we are not the only * function that looks up host names. */ if (!strchr(name, '.') && (cp = __hostalias(name))) name = cp; /* * disallow names consisting only of digits/dots, unless * they end in a dot. */ if (isdigit((unsigned char)name[0])) for (cp = name;; ++cp) { if (!*cp) { if (*--cp == '.') break; /* * All-numeric, no dot at the end. * Fake up a hostent as if we'd actually * done a lookup. */ if (inet_pton(af, name, resultbuf->__host_addr) <= 0) { *herr = HOST_NOT_FOUND; return NS_NOTFOUND; } strncpy(hostbuf, name, MAXDNAME); hostbuf[MAXDNAME] = '\0'; bp = hostbuf + MAXDNAME; len = buflen - MAXDNAME; resultbuf->h_name = hostbuf; resultbuf->h_aliases = resultbuf->__host_aliases; resultbuf->__host_aliases[0] = NULL; resultbuf->__host_addrs[0] = (char *)resultbuf->__host_addr; resultbuf->__host_addrs[1] = NULL; resultbuf->h_addr_list = resultbuf->__host_addrs; if (_res.options & RES_USE_INET6) _map_v4v6_hostent(resultbuf, &bp, &len); *herr = NETDB_SUCCESS; *(struct hostent **)rval = resultbuf; return NS_SUCCESS; } if (!isdigit((unsigned char)*cp) && *cp != '.') break; } if ((isxdigit((unsigned char)name[0]) && strchr(name, ':') != NULL) || name[0] == ':') for (cp = name;; ++cp) { if (!*cp) { if (*--cp == '.') break; /* * All-IPv6-legal, no dot at the end. * Fake up a hostent as if we'd actually * done a lookup. */ if (inet_pton(af, name, resultbuf->__host_addr) <= 0) { *herr = HOST_NOT_FOUND; return NS_NOTFOUND; } strncpy(hostbuf, name, MAXDNAME); hostbuf[MAXDNAME] = '\0'; bp = hostbuf + MAXDNAME; len = buflen - MAXDNAME; resultbuf->h_name = hostbuf; resultbuf->h_aliases = resultbuf->__host_aliases; resultbuf->__host_aliases[0] = NULL; resultbuf->__host_addrs[0] = (char *)resultbuf->__host_addr; resultbuf->__host_addrs[1] = NULL; resultbuf->h_addr_list = resultbuf->__host_addrs; *herr = NETDB_SUCCESS; *(struct hostent **)rval = resultbuf; return NS_SUCCESS; } if (!isxdigit((unsigned char)*cp) && *cp != ':' && *cp != '.') break; } if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) { dbgprintf("res_search failed (%d)\n", n); return NS_UNAVAIL; } *(struct hostent **)rval = gethostanswer(&buf, n, name, type, resultbuf, hostbuf, buflen, herr); return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;}int_dns_gethostbyaddr(void *rval, void *cb_data, va_list ap){ const char *addr; /* XXX should have been def'd as u_char! */ int len, af; const u_char *uaddr; static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; int n, size; querybuf buf; struct hostent *hp; char qbuf[MAXDNAME+1], *qp;#ifdef SUNSECURITY struct hostent *rhp; char **haddr; u_long old_options; char hname2[MAXDNAME+1];#endif /*SUNSECURITY*/ struct hostent *resultbuf; char *hostbuf; int buflen; int *herr; addr = va_arg(ap, const char *); uaddr = (const u_char *)addr; len = va_arg(ap, int); af = va_arg(ap, int); resultbuf = va_arg(ap, struct hostent *); hostbuf = va_arg(ap, char *); buflen = va_arg(ap, int); herr = va_arg(ap, int *); if ((_res.options & RES_INIT) == 0 && res_init() == -1) { *herr = NETDB_INTERNAL; return NS_UNAVAIL; } if (af == AF_INET6 && len == IN6ADDRSZ && (!memcmp(uaddr, mapped, sizeof mapped) || !memcmp(uaddr, tunnelled, sizeof tunnelled))) { /* Unmap. */ addr += sizeof mapped; uaddr += sizeof mapped; af = AF_INET; len = INADDRSZ; } switch (af) { case AF_INET: size = INADDRSZ; break; case AF_INET6: size = IN6ADDRSZ; break; default: errno = EAFNOSUPPORT; *herr = NETDB_INTERNAL; return NS_UNAVAIL; } if (size != len) { errno = EINVAL; *herr = NETDB_INTERNAL; return NS_UNAVAIL; } switch (af) { case AF_INET: (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", (uaddr[3] & 0xff), (uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff)); break; case AF_INET6: qp = qbuf; for (n = IN6ADDRSZ - 1; n >= 0; n--) { qp += SPRINTF((qp, "%x.%x.", uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf)); } strcpy(qp, "ip6.int"); break; default: abort(); } n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); if (n < 0) { dbgprintf("res_query failed (%d)\n", n); return NS_UNAVAIL; } if (n > sizeof buf.buf) { dbgprintf("static buffer is too small (%d)\n", n); return NS_UNAVAIL; } if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR, resultbuf, hostbuf, buflen, herr))) return NS_NOTFOUND; /* *herr was set by gethostanswer() */#ifdef SUNSECURITY if (af == AF_INET) { /* * turn off search as the name should be absolute, * 'localhost' should be matched by defnames */ strncpy(hname2, hp->h_name, MAXDNAME); hname2[MAXDNAME] = '\0'; old_options = _res.options; _res.options &= ~RES_DNSRCH; _res.options |= RES_DEFNAMES; if (!(rhp = gethostbyname(hname2))) { syslog(LOG_NOTICE|LOG_AUTH, "gethostbyaddr: No A record for %s (verifying [%s])", hname2, inet_ntoa(*((struct in_addr *)addr))); _res.options = old_options; *herr = HOST_NOT_FOUND; return NS_NOTFOUND; } _res.options = old_options; for (haddr = rhp->h_addr_list; *haddr; haddr++) if (!memcmp(*haddr, addr, INADDRSZ)) break; if (!*haddr) { syslog(LOG_NOTICE|LOG_AUTH, "gethostbyaddr: A record of %s != PTR record [%s]", hname2, inet_ntoa(*((struct in_addr *)addr))); *herr = HOST_NOT_FOUND; return NS_NOTFOUND; } }#endif /*SUNSECURITY*/ hp->h_addrtype = af; hp->h_length = len; bcopy(addr, resultbuf->__host_addr, len); resultbuf->__host_addrs[0] = (char *)resultbuf->__host_addr; resultbuf->__host_addrs[1] = NULL; if (af == AF_INET && (_res.options & RES_USE_INET6)) { _map_v4v6_address((char*)resultbuf->__host_addr, (char*)resultbuf->__host_addr); hp->h_addrtype = AF_INET6; hp->h_length = IN6ADDRSZ; } *herr = NETDB_SUCCESS; *(struct hostent **)rval = hp; return (hp != NULL) ? NS_SUCCESS : NS_NOTFOUND;}#ifdef RESOLVSORTstatic voidaddrsort(ap, num) char **ap; int num;{ int i, j; char **p; short aval[MAXADDRS]; int needsort = 0; p = ap; for (i = 0; i < num; i++, p++) { for (j = 0 ; (unsigned)j < _res.nsort; j++) if (_res.sort_list[j].addr.s_addr == (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) break; aval[i] = j; if (needsort == 0 && i > 0 && j < aval[i-1]) needsort = i; } if (!needsort) return; while (needsort < num) { for (j = needsort - 1; j >= 0; j--) { if (aval[j] > aval[j+1]) { char *hp; i = aval[j]; aval[j] = aval[j+1]; aval[j+1] = i; hp = ap[j]; ap[j] = ap[j+1]; ap[j+1] = hp; } else break; } needsort++; }}#endifvoid_sethostdnsent(stayopen) int stayopen;{ if ((_res.options & RES_INIT) == 0 && res_init() == -1) return; if (stayopen) _res.options |= RES_STAYOPEN | RES_USEVC;}void_endhostdnsent(){ _res.options &= ~(RES_STAYOPEN | RES_USEVC); res_close();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -