📄 resolv.c
字号:
break; DPRINTF("skipping T_SIG %d\n", i); free(a->dotted); pos += i; } DPRINTF("Answer name = |%s|\n", a->dotted); DPRINTF("Answer type = |%d|\n", a->atype); close(fd); if (outpacket) *outpacket = packet; else free(packet); return (0); /* success! */ tryall: /* if there are other nameservers, give them a go, otherwise return with error */ variant = 0; if (retries >= nscount*(searchdomains+1)) goto fail; again: /* if there are searchdomains, try them or fallback as passed */ if (variant < searchdomains) { /* next search */ variant++; } else { /* next server, first search */ ns = (ns + 1) % nscount; variant = 0; } }fail: if (fd != -1) close(fd); if (lookup) free(lookup); if (packet) free(packet); return -1;}#endif#ifdef L_resolveaddressint resolve_address(const char *address, int nscount, char **nsip, struct in_addr *in){ unsigned char *packet; struct resolv_answer a; char temp[256]; int i; int nest = 0; if (!address || !in) return -1; strncpy(temp, address, sizeof(temp)); for (;;) { i = dns_lookup(temp, T_A, nscount, nsip, &packet, &a); if (i < 0) return -1; free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ DPRINTF("Got a CNAME in resolve_address()\n"); i = decode_dotted(packet, a.rdoffset, temp, sizeof(temp)); free(packet); if (i < 0) return -1; if (++nest > MAX_RECURSE) return -1; continue; } else if (a.atype == T_A) { /* ADDRESS */ free(packet); break; } else { free(packet); return -1; } } if (in) memcpy(in, a.rdata, INADDRSZ); /* IPv4 T_A */ return 0;}#endif#ifdef L_resolvemailboxint resolve_mailbox(const char *address, int nscount, char **nsip, struct in_addr *in){ struct resolv_answer a; unsigned char *packet; char temp[256]; int nest = 0; int i; if (!address || !in) return -1; /* look up mail exchange */ i = dns_lookup(address, T_MX, nscount, nsip, &packet, &a); strncpy(temp, address, sizeof(temp)); if (i >= 0) { i = decode_dotted(packet, a.rdoffset+2, temp, sizeof(temp)); free(packet); } for (;;) { i = dns_lookup(temp, T_A, nscount, nsip, &packet, &a); if (i < 0) return -1; free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ DPRINTF("Got a CNAME in resolve_mailbox()\n"); i = decode_dotted(packet, a.rdoffset, temp, sizeof(temp)); free(packet); if (i < 0) return i; if (++nest > MAX_RECURSE) return -1; continue; } else if (a.atype == T_A) { /* ADDRESS */ free(packet); break; } else { free(packet); return -1; } } if (in) memcpy(in, a.rdata, INADDRSZ); /* IPv4 */ return 0;}#endif#ifdef L_opennameserversint nameservers;char * nameserver[MAX_SERVERS];int searchdomains;char * searchdomain[MAX_SEARCH];/* * we currently read formats not quite the same as that on normal * unix systems, we can have a list of nameservers after the keyword. */int open_nameservers(){ FILE *fp; int i;#define RESOLV_ARGS 5 char szBuffer[128], *p, *argv[RESOLV_ARGS]; int argc; if (nameservers > 0) return 0; if ((fp = fopen("/etc/resolv.conf", "r")) || (fp = fopen("/etc/config/resolv.conf", "r"))) { while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) { for (p = szBuffer; *p && isspace(*p); p++) /* skip white space */; if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */ continue; argc = 0; while (*p && argc < RESOLV_ARGS) { argv[argc++] = p; while (*p && !isspace(*p) && *p != '\n') p++; while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */ *p++ = '\0'; } if (strcmp(argv[0], "nameserver") == 0) { for (i = 1; i < argc && nameservers < MAX_SERVERS; i++) { nameserver[nameservers++] = strdup(argv[i]); DPRINTF("adding nameserver %s\n", argv[i]); } } /* domain and search are mutually exclusive, the last one wins */ if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) { while (searchdomains > 0) { free(searchdomain[--searchdomains]); searchdomain[searchdomains] = NULL; } for (i=1; i < argc && searchdomains < MAX_SEARCH; i++) { searchdomain[searchdomains++] = strdup(argv[i]); DPRINTF("adding search %s\n", argv[i]); } } } fclose(fp); } else { DPRINTF("failed to open %s\n", "resolv.conf"); } DPRINTF("nameservers = %d\n", nameservers); return 0;}#endif#ifdef L_closenameserversvoid close_nameservers(void){ while (nameservers > 0) { free(nameserver[--nameservers]); nameserver[nameservers] = NULL; } while (searchdomains > 0) { free(searchdomain[--searchdomains]); searchdomain[searchdomains] = NULL; }}#endif#ifdef L_resolvenameconst char *resolve_name(const char *name, int mailbox){ struct in_addr in; int i; /* shortcut: is it a valid IP address to begin with? */ if (inet_aton(name, &in)) return name; open_nameservers(); DPRINTF("looking up '%s', mailbox=%d, nameservers=%d\n", name, mailbox, nameservers); if (mailbox) i = resolve_mailbox(name, nameservers, nameserver, &in); else i = resolve_address(name, nameservers, nameserver, &in); if (i < 0) return 0; DPRINTF("success = '%s'\n", inet_ntoa(in)); return inet_ntoa(in);}#endif#ifdef L_gethostbynamestruct hostent *gethostbyname(const char *name){ static struct hostent h; static char namebuf[256]; static struct in_addr in; static struct in_addr *addr_list[2]; struct hostent *hp; unsigned char *packet; struct resolv_answer a; int i; int nest = 0; open_nameservers(); if (!name) return 0; if ((hp = get_hosts_byname(name))) /* do /etc/hosts first */ return(hp); memset(&h, 0, sizeof(h)); addr_list[0] = ∈ addr_list[1] = 0; strncpy(namebuf, name, sizeof(namebuf)); /* First check if this is already an address */ if (inet_aton(name, &in)) { h.h_name = namebuf; h.h_addrtype = AF_INET; h.h_length = sizeof(in); h.h_addr_list = (char **) addr_list; return &h; } for (;;) { i = dns_lookup(namebuf, 1, nameservers, nameserver, &packet, &a); if (i < 0) return 0; strncpy(namebuf, a.dotted, sizeof(namebuf)); free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ DPRINTF("Got a CNAME in gethostbyname()\n"); i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf)); free(packet); if (i < 0) return 0; if (++nest > MAX_RECURSE) return 0; continue; } else if (a.atype == T_A) { /* ADDRESS */ memcpy(&in, a.rdata, sizeof(in)); h.h_name = namebuf; h.h_addrtype = AF_INET; h.h_length = sizeof(in); h.h_addr_list = (char **) addr_list; free(packet); break; } else { free(packet); return 0; } } return &h;}#endif#ifdef L_gethostbyname2struct hostent *gethostbyname2(const char *name, int family){#ifndef __UCLIBC_HAS_IPV6__ return family == AF_INET ? gethostbyname(name) : (struct hostent*)0;#else /* __UCLIBC_HAS_IPV6__ */ static struct hostent h; static char namebuf[256]; static struct in6_addr in; static struct in6_addr *addr_list[2]; struct hostent *hp; unsigned char *packet; struct resolv_answer a; int i; int nest = 0; if (family == AF_INET) return gethostbyname(name); if (family != AF_INET6) return NULL; open_nameservers(); if (!name) return 0; if ((hp = get_hosts_byname(name))) /* do /etc/hosts first */ return(hp); memset(&h, 0, sizeof(h)); addr_list[0] = ∈ addr_list[1] = 0; strncpy(namebuf, name, sizeof(namebuf)); /* First check if this is already an address */ if (inet_pton(AF_INET6, name, &in)) { h.h_name = namebuf; h.h_addrtype = AF_INET6; h.h_length = sizeof(in); h.h_addr_list = (char **) addr_list; return &h; } for (;;) { i = dns_lookup(namebuf, T_AAAA, nameservers, nameserver, &packet, &a); if (i < 0) return 0; strncpy(namebuf, a.dotted, sizeof(namebuf)); free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ DPRINTF("Got a CNAME in gethostbyname()\n"); i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf)); free(packet); if (i < 0) return 0; if (++nest > MAX_RECURSE) return 0; continue; } else if (a.atype == T_AAAA) { /* ADDRESS */ memcpy(&in, a.rdata, sizeof(in)); h.h_name = namebuf; h.h_addrtype = AF_INET6; h.h_length = sizeof(in); h.h_addr_list = (char **) addr_list; free(packet); break; } else { free(packet); return 0; } } return &h;#endif /* __UCLIBC_HAS_IPV6__ */}#endif#ifdef L_getnetbynamestruct netent * getnetbyname(const char * name){ return NULL;}#endif#ifdef L_res_initint res_init(void){ return(0);}#endif#ifdef L_res_query#ifndef MIN#define MIN(x, y) ((x) < (y) ? (x) : (y))#endifint res_query(const char *dname, int class, int type, unsigned char *answer, int anslen){ unsigned char * packet = 0; struct resolv_answer a; int i; open_nameservers(); if (!dname || class != 1 /* CLASS_IN */) return(-1); memset((char *) &a, '\0', sizeof(a)); i = dns_lookup(dname, type, nameservers, nameserver, &packet, &a); if (i < 0) return(-1); free(a.dotted); if (a.atype == type) { /* CNAME*/ if (anslen && answer) memcpy(answer, a.rdata, MIN(anslen, a.rdlength)); if (packet) free(packet); return(MIN(anslen, a.rdlength)); } if (packet) free(packet); return 0;}#endif#ifdef L_gethostbyaddrstruct hostent *gethostbyaddr (const void *addr, socklen_t len, int type){ static struct hostent h; static char namebuf[256]; static struct in_addr in; static struct in_addr *addr_list[2]; struct hostent *hp; unsigned char *packet; struct resolv_answer a; int i; int nest = 0; if (!addr || (len != sizeof(in)) || (type != AF_INET)) return 0; if ((hp = get_hosts_byaddr(addr, len, type))) /* do /etc/hosts first */ return(hp); memcpy(&in.s_addr, addr, len); open_nameservers(); memset(&h, 0, sizeof(h)); addr_list[0] = ∈ addr_list[1] = 0; sprintf(namebuf, "%d.%d.%d.%d.in-addr.arpa", (in.s_addr >> 24) & 0xff, (in.s_addr >> 16) & 0xff, (in.s_addr >> 8) & 0xff, (in.s_addr >> 0) & 0xff); for (;;) { i = dns_lookup(namebuf, T_PTR, nameservers, nameserver, &packet, &a); if (i < 0) return 0; strncpy(namebuf, a.dotted, sizeof(namebuf)); free(a.dotted); if (a.atype == T_CNAME) { /* CNAME */ DPRINTF("Got a CNAME in gethostbyaddr()\n"); i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf)); free(packet); if (i < 0) return 0; if (++nest > MAX_RECURSE) return 0; continue; } else if (a.atype == T_PTR) { /* ADDRESS */ i = decode_dotted(packet, a.rdoffset, namebuf, sizeof(namebuf)); free(packet); h.h_name = namebuf; h.h_addrtype = AF_INET; h.h_length = sizeof(in); h.h_addr_list = (char **) addr_list; break; } else { free(packet); return 0; } } return &h;}#endif#ifdef L_read_etc_hostsstruct hostent * read_etc_hosts(const char * name, int ip){ static struct hostent h; static struct in_addr in; static struct in_addr *addr_list[2];#ifdef __UCLIBC_HAS_IPV6__ static struct in6_addr in6; static struct in6_addr *addr_list6[2];#endif /* __UCLIBC_HAS_IPV6__ */ static char line[80]; FILE *fp; char *cp;#define MAX_ALIAS 5 char *alias[MAX_ALIAS]; int aliases, i; if ((fp = fopen("/etc/hosts", "r")) == NULL && (fp = fopen("/etc/config/hosts", "r")) == NULL) return((struct hostent *) NULL); while (fgets(line, sizeof(line), fp)) { if ((cp = strchr(line, '#'))) *cp = '\0'; aliases = 0; cp = line; while (*cp) { while (*cp && isspace(*cp)) *cp++ = '\0'; if (!*cp) continue; if (aliases < MAX_ALIAS) alias[aliases++] = cp; while (*cp && !isspace(*cp)) cp++; } if (aliases < 2) continue; /* syntax error really */ if (ip) { if (strcmp(name, alias[0]) != 0) continue; } else { for (i = 1; i < aliases; i++) if (strcasecmp(name, alias[i]) == 0) break; if (i >= aliases) continue; }#ifndef __UCLIBC_HAS_IPV6__ if (inet_aton(alias[0], &in) == 0) break; /* bad ip address */#else /* __UCLIBC_HAS_IPV6__ */ if (inet_aton(alias[0], &in) == 0) { if (inet_pton(AF_INET6, alias[0], &in6) == 0) { addr_list6[0] = &in6; addr_list6[1] = 0; h.h_name = alias[1]; h.h_addrtype = AF_INET6; h.h_length = sizeof(in6); h.h_addr_list = (char**) addr_list6; fclose(fp); return(&h); } else break; /* bad ip address */ }#endif /* __UCLIBC_HAS_IPV6__ */ addr_list[0] = ∈ addr_list[1] = 0; h.h_name = alias[1]; h.h_addrtype = AF_INET; h.h_length = sizeof(in); h.h_addr_list = (char**) addr_list; fclose(fp); return(&h); } fclose(fp); return((struct hostent *) NULL);}#endif#ifdef L_get_hosts_bynamestruct hostent * get_hosts_byname(const char * name){ return(read_etc_hosts(name, 0));}#endif#ifdef L_get_hosts_byaddrstruct hostent * get_hosts_byaddr(const char * addr, int len, int type){ char ipaddr[20]; if (type != AF_INET || len != sizeof(struct in_addr)) return((struct hostent *) NULL); strcpy(ipaddr, inet_ntoa(* (struct in_addr *) addr)); return(read_etc_hosts(ipaddr, 1));}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -