--- embedaddon/dnsmasq/src/domain.c 2016/11/02 09:57:01 1.1.1.2 +++ embedaddon/dnsmasq/src/domain.c 2021/03/17 00:56:46 1.1.1.3 @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,22 +18,15 @@ static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c); -#ifdef HAVE_IPV6 static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c); -#endif -int is_name_synthetic(int flags, char *name, struct all_addr *addr) +int is_name_synthetic(int flags, char *name, union all_addr *addr) { char *p; struct cond_domain *c = NULL; - int prot = AF_INET; + int prot = (flags & F_IPV6) ? AF_INET6 : AF_INET; -#ifdef HAVE_IPV6 - if (flags & F_IPV6) - prot = AF_INET6; -#endif - for (c = daemon->synth_domains; c; c = c->next) { int found = 0; @@ -55,70 +48,123 @@ int is_name_synthetic(int flags, char *name, struct al if (pref && *pref != 0) continue; /* prefix match fail */ - - /* NB, must not alter name if we return zero */ - for (p = tail; *p; p++) + + if (c->indexed) { - char c = *p; + for (p = tail; *p; p++) + { + char c = *p; + + if (c < '0' || c > '9') + break; + } - if ((c >='0' && c <= '9') || c == '-') + if (*p != '.') continue; -#ifdef HAVE_IPV6 - if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f'))) - continue; -#endif + *p = 0; - break; + if (hostname_isequal(c->domain, p+1)) + { + if (prot == AF_INET) + { + unsigned int index = atoi(tail); + + if (!c->is6 && + index <= ntohl(c->end.s_addr) - ntohl(c->start.s_addr)) + { + addr->addr4.s_addr = htonl(ntohl(c->start.s_addr) + index); + found = 1; + } + } + else + { + u64 index = atoll(tail); + + if (c->is6 && + index <= addr6part(&c->end6) - addr6part(&c->start6)) + { + u64 start = addr6part(&c->start6); + addr->addr6 = c->start6; + setaddr6part(&addr->addr6, start + index); + found = 1; + } + } + } } - - if (*p != '.') - continue; - - *p = 0; - - /* swap . or : for - */ - for (p = tail; *p; p++) - if (*p == '-') - { - if (prot == AF_INET) - *p = '.'; -#ifdef HAVE_IPV6 - else - *p = ':'; -#endif - } - - if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr)) + else { - if (prot == AF_INET) + /* NB, must not alter name if we return zero */ + for (p = tail; *p; p++) { - if (!c->is6 && - ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) && - ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr)) - found = 1; + char c = *p; + + if ((c >='0' && c <= '9') || c == '-') + continue; + + if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f'))) + continue; + + break; } -#ifdef HAVE_IPV6 + + if (*p != '.') + continue; + + *p = 0; + + if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail) + { + /* special hack for v4-mapped. */ + memcpy(tail, "::ffff:", 7); + for (p = tail + 7; *p; p++) + if (*p == '-') + *p = '.'; + } else { - u64 addrpart = addr6part(&addr->addr.addr6); - - if (c->is6 && - is_same_net6(&addr->addr.addr6, &c->start6, 64) && - addrpart >= addr6part(&c->start6) && - addrpart <= addr6part(&c->end6)) - found = 1; + /* swap . or : for - */ + for (p = tail; *p; p++) + if (*p == '-') + { + if (prot == AF_INET) + *p = '.'; + else + *p = ':'; + } } -#endif + + if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr)) + { + if (prot == AF_INET) + { + if (!c->is6 && + ntohl(addr->addr4.s_addr) >= ntohl(c->start.s_addr) && + ntohl(addr->addr4.s_addr) <= ntohl(c->end.s_addr)) + found = 1; + } + else + { + u64 addrpart = addr6part(&addr->addr6); + + if (c->is6 && + is_same_net6(&addr->addr6, &c->start6, 64) && + addrpart >= addr6part(&c->start6) && + addrpart <= addr6part(&c->end6)) + found = 1; + } + } + } - + /* restore name */ for (p = tail; *p; p++) if (*p == '.' || *p == ':') *p = '-'; *p = '.'; - + + if (found) return 1; } @@ -127,58 +173,74 @@ int is_name_synthetic(int flags, char *name, struct al } -int is_rev_synth(int flag, struct all_addr *addr, char *name) +int is_rev_synth(int flag, union all_addr *addr, char *name) { struct cond_domain *c; - if (flag & F_IPV4 && (c = search_domain(addr->addr.addr4, daemon->synth_domains))) + if (flag & F_IPV4 && (c = search_domain(addr->addr4, daemon->synth_domains))) { char *p; *name = 0; - if (c->prefix) - strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN); + if (c->indexed) + { + unsigned int index = ntohl(addr->addr4.s_addr) - ntohl(c->start.s_addr); + snprintf(name, MAXDNAME, "%s%u", c->prefix ? c->prefix : "", index); + } + else + { + if (c->prefix) + strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN); - inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN); - for (p = name; *p; p++) - if (*p == '.') - *p = '-'; - + inet_ntop(AF_INET, &addr->addr4, name + strlen(name), ADDRSTRLEN); + for (p = name; *p; p++) + if (*p == '.') + *p = '-'; + } + strncat(name, ".", MAXDNAME); strncat(name, c->domain, MAXDNAME); return 1; } -#ifdef HAVE_IPV6 - if (flag & F_IPV6 && (c = search_domain6(&addr->addr.addr6, daemon->synth_domains))) + if ((flag & F_IPV6) && (c = search_domain6(&addr->addr6, daemon->synth_domains))) { char *p; *name = 0; - if (c->prefix) - strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN); + if (c->indexed) + { + u64 index = addr6part(&addr->addr6) - addr6part(&c->start6); + snprintf(name, MAXDNAME, "%s%llu", c->prefix ? c->prefix : "", index); + } + else + { + if (c->prefix) + strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN); - inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN); + inet_ntop(AF_INET6, &addr->addr6, name + strlen(name), ADDRSTRLEN); - /* IPv6 presentation address can start with ":", but valid domain names - cannot start with "-" so prepend a zero in that case. */ - if (!c->prefix && *name == ':') - { - *name = '0'; - inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN); + /* IPv6 presentation address can start with ":", but valid domain names + cannot start with "-" so prepend a zero in that case. */ + if (!c->prefix && *name == ':') + { + *name = '0'; + inet_ntop(AF_INET6, &addr->addr6, name+1, ADDRSTRLEN); + } + + /* V4-mapped have periods.... */ + for (p = name; *p; p++) + if (*p == ':' || *p == '.') + *p = '-'; + } - for (p = name; *p; p++) - if (*p == ':') - *p = '-'; - strncat(name, ".", MAXDNAME); strncat(name, c->domain, MAXDNAME); return 1; } -#endif return 0; } @@ -205,7 +267,7 @@ char *get_domain(struct in_addr addr) return daemon->domain_suffix; } -#ifdef HAVE_IPV6 + static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c) { u64 addrpart = addr6part(addr); @@ -229,4 +291,3 @@ char *get_domain6(struct in6_addr *addr) return daemon->domain_suffix; } -#endif