📄 resolv.c
字号:
if (buflen < sizeof(char *)*(ALIAS_DIM)) return ERANGE; alias=(char **)buf; buf+=sizeof(char **)*(ALIAS_DIM); buflen-=sizeof(char **)*(ALIAS_DIM); if (buflen<256) return ERANGE; strncpy(buf, name, buflen); alias[0] = buf; alias[1] = NULL; /* First check if this is already an address */ if (inet_aton(name, in)) { result_buf->h_name = buf; result_buf->h_addrtype = AF_INET; result_buf->h_length = sizeof(*in); result_buf->h_addr_list = (char **) addr_list; result_buf->h_aliases = alias; *result=result_buf; *h_errnop = NETDB_SUCCESS; return NETDB_SUCCESS; } for (;;) { BIGLOCK; __nameserversXX=__nameservers; __nameserverXX=__nameserver; BIGUNLOCK; i = __dns_lookup(buf, T_A, __nameserversXX, __nameserverXX, &packet, &a); if (i < 0) { *h_errnop = HOST_NOT_FOUND; DPRINTF("__dns_lookup\n"); return TRY_AGAIN; } strncpy(buf, a.dotted, buflen); free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ DPRINTF("Got a CNAME in gethostbyname()\n"); i = __decode_dotted(packet, a.rdoffset, buf, buflen); free(packet); if (i < 0) { *h_errnop = NO_RECOVERY; DPRINTF("__decode_dotted\n"); return -1; } if (++nest > MAX_RECURSE) { *h_errnop = NO_RECOVERY; DPRINTF("recursion\n"); return -1; } continue; } else if (a.atype == T_A) { /* ADDRESS */ memcpy(in, a.rdata, sizeof(*in)); result_buf->h_name = buf; result_buf->h_addrtype = AF_INET; result_buf->h_length = sizeof(*in); result_buf->h_addr_list = (char **) addr_list;#ifdef __UCLIBC_MJN3_ONLY__#warning TODO -- generate the full list#endif result_buf->h_aliases = alias; /* TODO: generate the full list */ free(packet); break; } else { free(packet); *h_errnop=HOST_NOT_FOUND; return TRY_AGAIN; } } *result=result_buf; *h_errnop = NETDB_SUCCESS; return NETDB_SUCCESS;}#endif#ifdef L_gethostbyname2_rint gethostbyname2_r(const char *name, int family, struct hostent * result_buf, char * buf, size_t buflen, struct hostent ** result, int * h_errnop){#ifndef __UCLIBC_HAS_IPV6__ return family == AF_INET ? gethostbyname_r(name, result_buf, buf, buflen, result, h_errnop) : HOST_NOT_FOUND;#else /* __UCLIBC_HAS_IPV6__ */ struct in6_addr *in; struct in6_addr **addr_list; unsigned char *packet; struct resolv_answer a; int i; int nest = 0; int __nameserversXX; char ** __nameserverXX; if (family == AF_INET) return gethostbyname_r(name, result_buf, buf, buflen, result, h_errnop); if (family != AF_INET6) return EINVAL; __open_nameservers(); *result=NULL; if (!name) return EINVAL; /* do /etc/hosts first */ { int old_errno = errno; /* Save the old errno and reset errno */ __set_errno(0); /* to check for missing /etc/hosts. */ if ((i=__get_hosts_byname_r(name, AF_INET, result_buf, buf, buflen, result, h_errnop))==0) return i; switch (*h_errnop) { case HOST_NOT_FOUND: case NO_ADDRESS: break; case NETDB_INTERNAL: if (errno == ENOENT) { break; } /* else fall through */ default: return i; } __set_errno(old_errno); } DPRINTF("Nothing found in /etc/hosts\n"); *h_errnop = NETDB_INTERNAL; if (buflen < sizeof(*in)) return ERANGE; in=(struct in6_addr*)buf; buf+=sizeof(*in); buflen-=sizeof(*in); if (buflen < sizeof(*addr_list)*2) return ERANGE; addr_list=(struct in6_addr**)buf; buf+=sizeof(*addr_list)*2; buflen-=sizeof(*addr_list)*2; addr_list[0] = in; addr_list[1] = 0; if (buflen<256) return ERANGE; strncpy(buf, name, buflen); /* First check if this is already an address */ if (inet_pton(AF_INET6, name, in)) { result_buf->h_name = buf; result_buf->h_addrtype = AF_INET6; result_buf->h_length = sizeof(*in); result_buf->h_addr_list = (char **) addr_list; *result=result_buf; *h_errnop = NETDB_SUCCESS; return NETDB_SUCCESS; } for (;;) { BIGLOCK; __nameserversXX=__nameservers; __nameserverXX=__nameserver; BIGUNLOCK; i = __dns_lookup(buf, T_AAAA, __nameserversXX, __nameserverXX, &packet, &a); if (i < 0) { *h_errnop = HOST_NOT_FOUND; return TRY_AGAIN; } strncpy(buf, a.dotted, buflen); free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ DPRINTF("Got a CNAME in gethostbyname()\n"); i = __decode_dotted(packet, a.rdoffset, buf, buflen); free(packet); if (i < 0) { *h_errnop = NO_RECOVERY; return -1; } if (++nest > MAX_RECURSE) { *h_errnop = NO_RECOVERY; return -1; } continue; } else if (a.atype == T_AAAA) { /* ADDRESS */ memcpy(in, a.rdata, sizeof(*in)); result_buf->h_name = buf; result_buf->h_addrtype = AF_INET6; result_buf->h_length = sizeof(*in); result_buf->h_addr_list = (char **) addr_list; free(packet); break; } else { free(packet); *h_errnop=HOST_NOT_FOUND; return TRY_AGAIN; } } *result=result_buf; *h_errnop = NETDB_SUCCESS; return NETDB_SUCCESS;#endif /* __UCLIBC_HAS_IPV6__ */}#endif#ifdef L_gethostbyaddr_rint gethostbyaddr_r (const void *addr, socklen_t len, int type, struct hostent * result_buf, char * buf, size_t buflen, struct hostent ** result, int * h_errnop){ struct in_addr *in; struct in_addr **addr_list;#ifdef __UCLIBC_HAS_IPV6__ char *qp; size_t plen; struct in6_addr *in6; struct in6_addr **addr_list6;#endif /* __UCLIBC_HAS_IPV6__ */ unsigned char *packet; struct resolv_answer a; int i; int nest = 0; int __nameserversXX; char ** __nameserverXX; *result=NULL; if (!addr) return EINVAL; switch (type) { case AF_INET: if (len != sizeof(struct in_addr)) return EINVAL; break;#ifdef __UCLIBC_HAS_IPV6__ case AF_INET6: if (len != sizeof(struct in6_addr)) return EINVAL; break;#endif /* __UCLIBC_HAS_IPV6__ */ default: return EINVAL; } /* do /etc/hosts first */ if ((i=__get_hosts_byaddr_r(addr, len, type, result_buf, buf, buflen, result, h_errnop))==0) return i; switch (*h_errnop) { case HOST_NOT_FOUND: case NO_ADDRESS: break; default: return i; } __open_nameservers();#ifdef __UCLIBC_HAS_IPV6__ qp=buf; plen=buflen;#endif /* __UCLIBC_HAS_IPV6__ */ *h_errnop = NETDB_INTERNAL; if (buflen < sizeof(*in)) return ERANGE; in=(struct in_addr*)buf; buf+=sizeof(*in); buflen-=sizeof(*in); if (buflen < sizeof(*addr_list)*2) return ERANGE; addr_list=(struct in_addr**)buf; buf+=sizeof(*addr_list)*2; buflen-=sizeof(*addr_list)*2;#ifdef __UCLIBC_HAS_IPV6__ if (plen < sizeof(*in6)) return ERANGE; in6=(struct in6_addr*)qp; qp+=sizeof(*in6); plen-=sizeof(*in6); if (plen < sizeof(*addr_list6)*2) return ERANGE; addr_list6=(struct in6_addr**)qp; qp+=sizeof(*addr_list6)*2; plen-=sizeof(*addr_list6)*2; if (plen < buflen) { buflen=plen; buf=qp; }#endif /* __UCLIBC_HAS_IPV6__ */ if (buflen<256) return ERANGE; if(type == AF_INET) { unsigned char *tmp_addr = (unsigned char *)addr; memcpy(&in->s_addr, addr, len); addr_list[0] = in; sprintf(buf, "%u.%u.%u.%u.in-addr.arpa", tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]);#ifdef __UCLIBC_HAS_IPV6__ } else { memcpy(in6->s6_addr, addr, len); addr_list6[0] = in6; qp = buf; for (i = len - 1; i >= 0; i--) { qp += sprintf(qp, "%x.%x.", in6->s6_addr[i] & 0xf, (in6->s6_addr[i] >> 4) & 0xf); } strcpy(qp, "ip6.int");#endif /* __UCLIBC_HAS_IPV6__ */ } addr_list[1] = 0; for (;;) { BIGLOCK; __nameserversXX=__nameservers; __nameserverXX=__nameserver; BIGUNLOCK; i = __dns_lookup(buf, T_PTR, __nameserversXX, __nameserverXX, &packet, &a); if (i < 0) { *h_errnop = HOST_NOT_FOUND; return TRY_AGAIN; } strncpy(buf, a.dotted, buflen); free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ DPRINTF("Got a CNAME in gethostbyaddr()\n"); i = __decode_dotted(packet, a.rdoffset, buf, buflen); free(packet); if (i < 0) { *h_errnop = NO_RECOVERY; return -1; } if (++nest > MAX_RECURSE) { *h_errnop = NO_RECOVERY; return -1; } continue; } else if (a.atype == T_PTR) { /* ADDRESS */ i = __decode_dotted(packet, a.rdoffset, buf, buflen); free(packet); result_buf->h_name = buf; result_buf->h_addrtype = type; if(type == AF_INET) { result_buf->h_length = sizeof(*in);#ifdef __UCLIBC_HAS_IPV6__ } else { result_buf->h_length = sizeof(*in6);#endif /* __UCLIBC_HAS_IPV6__ */ } result_buf->h_addr_list = (char **) addr_list; break; } else { free(packet); *h_errnop = NO_ADDRESS; return TRY_AGAIN; } } *result=result_buf; *h_errnop = NETDB_SUCCESS; return NETDB_SUCCESS;}#endif#ifdef L_res_comp/* * Expand compressed domain name 'comp_dn' to full domain name. * 'msg' is a pointer to the begining of the message, * 'eomorig' points to the first location after the message, * 'exp_dn' is a pointer to a buffer of size 'length' for the result. * Return size of compressed name or -1 if there was an error. */int __dn_expand(const u_char *msg, const u_char *eom, const u_char *src, char *dst, int dstsiz){ int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz); if (n > 0 && dst[0] == '.') dst[0] = '\0'; return (n);}#endif /* L_res_comp */#ifdef L_ns_name/* * printable(ch) * Thinking in noninternationalized USASCII (per the DNS spec), * is this character visible and not a space when printed ? * return: * boolean. */static int printable(int ch) { return (ch > 0x20 && ch < 0x7f);}/* * special(ch) * Thinking in noninternationalized USASCII (per the DNS spec), * is this characted special ("in need of quoting") ? * return: * boolean. */static int special(int ch) { switch (ch) { case 0x22: /* '"' */ case 0x2E: /* '.' */ case 0x3B: /* ';' */ case 0x5C: /* '\\' */ /* Special modifiers in zone files. */ case 0x40: /* '@' */ case 0x24: /* '$' */ return (1); default: return (0); }}/* * ns_name_uncompress(msg, eom, src, dst, dstsiz) * Expand compressed domain name to presentation format. * return: * Number of bytes read out of `src', or -1 (with errno set). * note: * Root domain returns as "." not "". */int __ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src, char *dst, size_t dstsiz){ u_char tmp[NS_MAXCDNAME]; int n; if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1) return (-1); if (ns_name_ntop(tmp, dst, dstsiz) == -1) return (-1); return (n);}/* * ns_name_ntop(src, dst, dstsiz) * Convert an encoded domain name to printable ascii as per RFC1035. * return: * Number of bytes written to buffer, or -1 (with errno set) * notes: * The root is returned as "." * All other domains are returned in non absolute form */int __ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) { const u_char *cp; char *dn, *eom; u_char c; u_int n; const char digits[] = "0123456789"; cp = src; dn = dst; eom = dst + dstsiz; while ((n = *cp++) != 0) { if ((n & NS_CMPRSFLGS) != 0) { /* Some kind of compression pointer. */ __set_errno (EMSGSIZE); return (-1); } if (dn != dst) { if (dn >= eom) { __set_errno (EMSGSIZE); return (-1); } *dn++ = '.'; } if (dn + n >= eom) { __set_errno (EMSGSIZE); return (-1); } for ((void)NULL; n > 0; n--) { c = *cp++; if (special(c)) { if (dn + 1 >= eom) { __set_errno (EMSGSIZE); return (-1); } *dn++ = '\\'; *dn++ = (char)c; } else if (!printable(c)) { if (dn + 3 >= eom) { __set_errno (EMSGSIZE); return (-1); } *dn++ = '\\'; *dn++ = digits[c / 100]; *dn++ = digits[(c % 100) / 10]; *dn++ = digits[c % 10]; } else { if (dn >= eom) { __set_errno (EMSGSIZE); return (-1); } *dn++ = (char)c; } } } if (dn == dst) { if (dn >= eom) { __set_errno (EMSGSIZE); return (-1); } *dn++ = '.'; } if (dn >= eom) { __set_errno (EMSGSIZE); return (-1); } *dn++ = '\0'; return (dn - dst);}/* * ns_name_unpack(msg, eom, src, dst, dstsiz) * Unpack a domain name from a message, source may be compressed. * return: * -1 if it fails, or consumed octets if it succeeds. */int __ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, u_char *dst, size_t dstsiz){ const u_char *srcp, *dstlim; u_char *dstp; int n, len, checked; len = -1; checked = 0; dstp = dst; srcp = src; dstlim = dst + dstsiz; if (srcp < msg || srcp >= eom) { __set_errno (EMSGSIZE); return (-1); } /* Fetch next label in domain name. */ while ((n = *srcp++) != 0) { /* Check for indirection. */ switch (n & NS_CMPRSFLGS) { case 0: /* Limit checks. */ if (dstp + n + 1 >= dstlim || srcp + n >= eom) { __set_errno (EMSGSIZE); return (-1); } checked += n + 1; *dstp++ = n; memcpy(dstp, srcp, n); dstp += n; srcp += n; break; case NS_CMPRSFLGS: if (srcp >= eom) { __set_errno (EMSGSIZE); return (-1); } if (len < 0) len = srcp - src + 1; srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff)); if (srcp < msg || srcp >= eom) { /* Out of range. */ __set_errno (EMSGSIZE); return (-1); } checked += 2; /* * Check for loops in the compressed name; * if we've looked at the whole message, * there must be a loop. */ if (checked >= eom - msg) { __set_errno (EMSGSIZE); return (-1); } break; default: __set_errno (EMSGSIZE); return (-1); /* flag error */ } } *dstp = '\0'; if (len < 0) len = srcp - src; return (len);}#endif /* L_ns_name */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -