📄 name6.c
字号:
hp->h_aliases = aliases; nalias = 0; for (i = 1; i <= 2; i++) { if ((pp = HP(i)->h_aliases) == NULL) continue; for (; nalias < MAXALIASES && *pp != NULL; pp++) { /* check duplicates */ for (j = 0; j < nalias; j++) if (strcasecmp(*pp, aliases[j]) == 0) break; if (j == nalias) aliases[nalias++] = *pp; } } aliases[nalias] = NULL;#ifdef INET6 if (hp1->h_length != hp2->h_length) { hp->h_addrtype = AF_INET6; hp->h_length = sizeof(struct in6_addr); } else {#endif hp->h_addrtype = hp1->h_addrtype; hp->h_length = hp1->h_length;#ifdef INET6 }#endif hp->h_addr_list = addrs; naddr = 0; for (i = 1; i <= 2; i++) { if ((pp = HP(i)->h_addr_list) == NULL) continue; if (HP(i)->h_length == hp->h_length) { while (naddr < MAXADDRS && *pp != NULL) addrs[naddr++] = *pp++; } else { /* copy IPv4 addr as mapped IPv6 addr */ while (naddr < MAXADDRS && *pp != NULL) { MAPADDR(&addrbuf[naddr], *pp++); addrs[naddr] = (char *)&addrbuf[naddr]; naddr++; } } } addrs[naddr] = NULL; hp = _hpcopy(hp, errp); freehostent(hp1); freehostent(hp2); return hp;}/* * _hpmapv6: convert IPv4 hostent into IPv4-mapped IPv6 addresses */#ifdef INET6static struct hostent *_hpmapv6(struct hostent *hp, int *errp){ struct hostent *hp6; if (hp == NULL) return NULL; if (hp->h_addrtype == AF_INET6) return hp; /* make dummy hostent to convert IPv6 address */ if ((hp6 = (struct hostent *)malloc(sizeof(struct hostent))) == NULL) { *errp = TRY_AGAIN; return NULL; } hp6->h_name = NULL; hp6->h_aliases = NULL; hp6->h_addrtype = AF_INET6; hp6->h_length = sizeof(struct in6_addr); hp6->h_addr_list = NULL; return _hpmerge(hp6, hp, errp);}#endif/* * _hpsort: sort address by sortlist */static struct hostent *_hpsort(struct hostent *hp){ int i, j, n; u_char *ap, *sp, *mp, **pp; char t; char order[MAXADDRS]; int nsort = _res.nsort; if (hp == NULL || hp->h_addr_list[1] == NULL || nsort == 0) return hp; for (i = 0; (ap = (u_char *)hp->h_addr_list[i]); i++) { for (j = 0; j < nsort; j++) {#ifdef INET6 if (_res_ext.sort_list[j].af != hp->h_addrtype) continue; sp = (u_char *)&_res_ext.sort_list[j].addr; mp = (u_char *)&_res_ext.sort_list[j].mask;#else sp = (u_char *)&_res.sort_list[j].addr; mp = (u_char *)&_res.sort_list[j].mask;#endif for (n = 0; n < hp->h_length; n++) { if ((ap[n] & mp[n]) != sp[n]) break; } if (n == hp->h_length) break; } order[i] = j; } n = i; pp = (u_char **)hp->h_addr_list; for (i = 0; i < n - 1; i++) { for (j = i + 1; j < n; j++) { if (order[i] > order[j]) { ap = pp[i]; pp[i] = pp[j]; pp[j] = ap; t = order[i]; order[i] = order[j]; order[j] = t; } } } return hp;}static char *_hgetword(char **pp){ char c, *p, *ret; const char *sp; static const char sep[] = "# \t\n"; ret = NULL; for (p = *pp; (c = *p) != '\0'; p++) { for (sp = sep; *sp != '\0'; sp++) { if (c == *sp) break; } if (c == '#') p[1] = '\0'; /* ignore rest of line */ if (ret == NULL) { if (*sp == '\0') ret = p; } else { if (*sp != '\0') { *p++ = '\0'; break; } } } *pp = p; if (ret == NULL || *ret == '\0') return NULL; return ret;}/* * FILES (/etc/hosts) */static FILE *_files_open(int *errp){ FILE *fp; fp = fopen(_PATH_HOSTS, "r"); if (fp == NULL) *errp = NO_RECOVERY; return fp;}static int_files_ghbyname(void *rval, void *cb_data, va_list ap){ const char *name; int af; int *errp; int match, nalias; char *p, *line, *addrstr, *cname; FILE *fp; struct hostent *rethp, *hp, hpbuf; char *aliases[MAXALIASES + 1], *addrs[2]; union inx_addr addrbuf; char buf[BUFSIZ]; int af0; name = va_arg(ap, const char *); af = va_arg(ap, int); errp = va_arg(ap, int *); *(struct hostent **)rval = NULL; if ((fp = _files_open(errp)) == NULL) return NS_UNAVAIL; rethp = hp = NULL; af0 = af; while (fgets(buf, sizeof(buf), fp)) { line = buf; if ((addrstr = _hgetword(&line)) == NULL || (cname = _hgetword(&line)) == NULL) continue; match = (strcasecmp(cname, name) == 0); nalias = 0; while ((p = _hgetword(&line)) != NULL) { if (!match) match = (strcasecmp(p, name) == 0); if (nalias < MAXALIASES) aliases[nalias++] = p; } if (!match) continue; switch (af0) { case AF_INET: if (inet_aton(addrstr, (struct in_addr *)&addrbuf) != 1) { *errp = NO_DATA; /* name found */ continue; } af = af0; break;#ifdef INET6 case AF_INET6: if (inet_pton(af, addrstr, &addrbuf) != 1) { *errp = NO_DATA; /* name found */ continue; } af = af0; break;#endif case AF_UNSPEC: if (inet_aton(addrstr, (struct in_addr *)&addrbuf) == 1) { af = AF_INET; break; }#ifdef INET6 if (inet_pton(AF_INET6, addrstr, &addrbuf) == 1) { af = AF_INET6; break; }#endif *errp = NO_DATA; /* name found */ continue; /* NOTREACHED */ } hp = &hpbuf; hp->h_name = cname; hp->h_aliases = aliases; aliases[nalias] = NULL; hp->h_addrtype = af; hp->h_length = ADDRLEN(af); hp->h_addr_list = addrs; addrs[0] = (char *)&addrbuf; addrs[1] = NULL; hp = _hpcopy(hp, errp); rethp = _hpmerge(rethp, hp, errp); } fclose(fp); *(struct hostent **)rval = rethp; return (rethp != NULL) ? NS_SUCCESS : NS_NOTFOUND;}static int_files_ghbyaddr(void *rval, void *cb_data, va_list ap){ const void *addr; int addrlen; int af; int *errp; int nalias; char *p, *line; FILE *fp; struct hostent *hp, hpbuf; char *aliases[MAXALIASES + 1], *addrs[2]; union inx_addr addrbuf; char buf[BUFSIZ]; addr = va_arg(ap, const void *); addrlen = va_arg(ap, int); af = va_arg(ap, int); errp = va_arg(ap, int *); *(struct hostent**)rval = NULL; if ((fp = _files_open(errp)) == NULL) return NS_UNAVAIL; hp = NULL; while (fgets(buf, sizeof(buf), fp)) { line = buf; if ((p = _hgetword(&line)) == NULL || (af == AF_INET ? inet_aton(p, (struct in_addr *)&addrbuf) : inet_pton(af, p, &addrbuf)) != 1 || memcmp(addr, &addrbuf, addrlen) != 0 || (p = _hgetword(&line)) == NULL) continue; hp = &hpbuf; hp->h_name = p; hp->h_aliases = aliases; nalias = 0; while ((p = _hgetword(&line)) != NULL) { if (nalias < MAXALIASES) aliases[nalias++] = p; } aliases[nalias] = NULL; hp->h_addrtype = af; hp->h_length = addrlen; hp->h_addr_list = addrs; addrs[0] = (char *)&addrbuf; addrs[1] = NULL; hp = _hpcopy(hp, errp); break; } fclose(fp); *(struct hostent **)rval = hp; return (hp != NULL) ? NS_SUCCESS : NS_NOTFOUND;}#ifdef YP/* * NIS * * XXX actually a hack, these are INET4 specific. */static int_nis_ghbyname(void *rval, void *cb_data, va_list ap){ const char *name; int af; int *errp; struct hostent *hp = NULL; name = va_arg(ap, const char *); af = va_arg(ap, int); errp = va_arg(ap, int *); if (af == AF_UNSPEC) af = AF_INET; if (af == AF_INET) { hp = _gethostbynisname(name, af); if (hp != NULL) hp = _hpcopy(hp, errp); } *(struct hostent **)rval = hp; return (hp != NULL) ? NS_SUCCESS : NS_NOTFOUND; }static int_nis_ghbyaddr(void *rval, void *cb_data, va_list ap){ const void *addr; int addrlen; int af; int *errp; struct hostent *hp = NULL; addr = va_arg(ap, const void *); addrlen = va_arg(ap, int); af = va_arg(ap, int); if (af == AF_INET) { hp = _gethostbynisaddr(addr, addrlen, af); if (hp != NULL) hp = _hpcopy(hp, errp); } *(struct hostent **)rval = hp; return (hp != NULL) ? NS_SUCCESS : NS_NOTFOUND;}#endiftypedef struct __res_type_list res_type_list;struct __res_type_list { res_type_list * rtl_entry; int rtl_type;};#if PACKETSZ > 1024#define MAXPACKET PACKETSZ#else#define MAXPACKET 1024#endiftypedef union { HEADER hdr; u_char buf[MAXPACKET];} querybuf;static struct hostent *getanswer(const querybuf *, int, const char *, int, struct hostent *, int *);/* * we don't need to take care about sorting, nor IPv4 mapped address here. */static struct hostent *getanswer(answer, anslen, qname, qtype, template, errp) const querybuf *answer; int anslen; const char *qname; int qtype; struct hostent *template; int *errp;{ const HEADER *hp; const u_char *cp; int n; const u_char *eom, *erdata; char *bp, **ap, **hap; int type, class, buflen, ancount, qdcount; int haveanswer, had_error; char tbuf[MAXDNAME]; const char *tname; int (*name_ok)(const char *); static char *h_addr_ptrs[MAXADDRS + 1]; static char *host_aliases[MAXALIASES]; static char hostbuf[8*1024];#define BOUNDED_INCR(x) \ do { \ cp += x; \ if (cp > eom) { \ *errp = NO_RECOVERY; \ return (NULL); \ } \ } while (0)#define BOUNDS_CHECK(ptr, count) \ do { \ if ((ptr) + (count) > eom) { \ *errp = NO_RECOVERY; \ return (NULL); \ } \ } while (0)/* XXX do {} while (0) cannot be put here */#define DNS_ASSERT(x) \ { \ if (!(x)) { \ cp += n; \ continue; \ } \ }/* XXX do {} while (0) cannot be put here */#define DNS_FATAL(x) \ { \ if (!(x)) { \ had_error++; \ continue; \ } \ } tname = qname; template->h_name = NULL; eom = answer->buf + anslen; switch (qtype) { case T_A: case T_AAAA: name_ok = res_hnok; break; case T_PTR: name_ok = res_dnok; break; default: return (NULL); /* XXX should be abort(); */ } /* * find first satisfactory answer */ hp = &answer->hdr; ancount = ntohs(hp->ancount); qdcount = ntohs(hp->qdcount); bp = hostbuf; buflen = sizeof hostbuf; cp = answer->buf; BOUNDED_INCR(HFIXEDSZ); if (qdcount != 1) { *errp = NO_RECOVERY; return (NULL); } n = dn_expand(answer->buf, eom, cp, bp, buflen); if ((n < 0) || !(*name_ok)(bp)) { *errp = NO_RECOVERY; return (NULL); } BOUNDED_INCR(n + QFIXEDSZ); if (qtype == T_A || qtype == T_AAAA) { /* res_send() has already verified that the query name is the * same as the one we sent; this just gets the expanded name * (i.e., with the succeeding search-domain tacked on). */ n = strlen(bp) + 1; /* for the \0 */ if (n >= MAXHOSTNAMELEN) { *errp = NO_RECOVERY; return (NULL); } template->h_name = bp; bp += n; buflen -= n; /* The qname can be abbreviated, but h_name is now absolute. */ qname = template->h_name; } ap = host_aliases; *ap = NULL; template->h_aliases = host_aliases; hap = h_addr_ptrs; *hap = NULL; template->h_addr_list = h_addr_ptrs; haveanswer = 0; had_error = 0; while (ancount-- > 0 && cp < eom && !had_error) { n = dn_expand(answer->buf, eom, cp, bp, buflen); DNS_FATAL(n >= 0); DNS_FATAL((*name_ok)(bp)); cp += n; /* name */ BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ); type = _getshort(cp); cp += INT16SZ; /* type */ class = _getshort(cp); cp += INT16SZ + INT32SZ; /* class, TTL */ n = _getshort(cp); cp += INT16SZ; /* len */ BOUNDS_CHECK(cp, n); erdata = cp + n; DNS_ASSERT(class == C_IN); if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { if (ap >= &host_aliases[MAXALIASES-1]) continue; n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); DNS_FATAL(n >= 0); DNS_FATAL((*name_ok)(tbuf)); cp += n; if (cp != erdata) { *errp = NO_RECOVERY; return (NULL); } /* Store alias. */ *ap++ = bp; n = strlen(bp) + 1; /* for the \0 */ DNS_FATAL(n < MAXHOSTNAMELEN); bp += n; buflen -= n; /* Get canonical name. */ n = strlen(tbuf) + 1; /* for the \0 */ DNS_FATAL(n <= buflen); DNS_FATAL(n < MAXHOSTNAMELEN); strcpy(bp, tbuf); template->h_name = bp; bp += n; buflen -= n; continue; } if (qtype == T_PTR && type == T_CNAME) { n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); if (n < 0 || !res_dnok(tbuf)) { had_error++; continue; } cp += n; if (cp != erdata) { *errp = NO_RECOVERY; return (NULL); } /* Get canonical name. */ n = strlen(tbuf) + 1; /* for the \0 */ if (n > buflen || n >= MAXHOSTNAMELEN) { had_error++; continue; } strcpy(bp, tbuf); tname = bp; bp += n; buflen -= n; continue; } DNS_ASSERT(type == qtype); switch (type) { case T_PTR: DNS_ASSERT(strcasecmp(tname, bp) == 0); n = dn_expand(answer->buf, eom, cp, bp, buflen); DNS_FATAL(n >= 0); DNS_FATAL(res_hnok(bp));#if MULTI_PTRS_ARE_ALIASES cp += n; if (cp != erdata) { *errp = NO_RECOVERY; return (NULL); } if (!haveanswer) template->h_name = bp; else if (ap < &host_aliases[MAXALIASES-1]) *ap++ = bp; else n = -1; if (n != -1) { n = strlen(bp) + 1; /* for the \0 */ if (n >= MAXHOSTNAMELEN) { had_error++; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -