Annotation of embedaddon/dnsmasq/src/domain.c, revision 1.1.1.3
1.1.1.3 ! misho 1: /* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
1.1 misho 2:
3: This program is free software; you can redistribute it and/or modify
4: it under the terms of the GNU General Public License as published by
5: the Free Software Foundation; version 2 dated June, 1991, or
6: (at your option) version 3 dated 29 June, 2007.
7:
8: This program is distributed in the hope that it will be useful,
9: but WITHOUT ANY WARRANTY; without even the implied warranty of
10: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11: GNU General Public License for more details.
12:
13: You should have received a copy of the GNU General Public License
14: along with this program. If not, see <http://www.gnu.org/licenses/>.
15: */
16:
17: #include "dnsmasq.h"
18:
19:
20: static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c);
21: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
22:
23:
1.1.1.3 ! misho 24: int is_name_synthetic(int flags, char *name, union all_addr *addr)
1.1 misho 25: {
26: char *p;
27: struct cond_domain *c = NULL;
1.1.1.3 ! misho 28: int prot = (flags & F_IPV6) ? AF_INET6 : AF_INET;
1.1 misho 29:
30: for (c = daemon->synth_domains; c; c = c->next)
31: {
32: int found = 0;
33: char *tail, *pref;
34:
35: for (tail = name, pref = c->prefix; *tail != 0 && pref && *pref != 0; tail++, pref++)
36: {
37: unsigned int c1 = (unsigned char) *pref;
38: unsigned int c2 = (unsigned char) *tail;
39:
40: if (c1 >= 'A' && c1 <= 'Z')
41: c1 += 'a' - 'A';
42: if (c2 >= 'A' && c2 <= 'Z')
43: c2 += 'a' - 'A';
44:
45: if (c1 != c2)
46: break;
47: }
48:
49: if (pref && *pref != 0)
50: continue; /* prefix match fail */
1.1.1.3 ! misho 51:
! 52: if (c->indexed)
1.1 misho 53: {
1.1.1.3 ! misho 54: for (p = tail; *p; p++)
! 55: {
! 56: char c = *p;
! 57:
! 58: if (c < '0' || c > '9')
! 59: break;
! 60: }
1.1 misho 61:
1.1.1.3 ! misho 62: if (*p != '.')
1.1 misho 63: continue;
64:
1.1.1.3 ! misho 65: *p = 0;
1.1 misho 66:
1.1.1.3 ! misho 67: if (hostname_isequal(c->domain, p+1))
! 68: {
! 69: if (prot == AF_INET)
! 70: {
! 71: unsigned int index = atoi(tail);
! 72:
! 73: if (!c->is6 &&
! 74: index <= ntohl(c->end.s_addr) - ntohl(c->start.s_addr))
! 75: {
! 76: addr->addr4.s_addr = htonl(ntohl(c->start.s_addr) + index);
! 77: found = 1;
! 78: }
! 79: }
! 80: else
! 81: {
! 82: u64 index = atoll(tail);
! 83:
! 84: if (c->is6 &&
! 85: index <= addr6part(&c->end6) - addr6part(&c->start6))
! 86: {
! 87: u64 start = addr6part(&c->start6);
! 88: addr->addr6 = c->start6;
! 89: setaddr6part(&addr->addr6, start + index);
! 90: found = 1;
! 91: }
! 92: }
! 93: }
1.1 misho 94: }
1.1.1.3 ! misho 95: else
1.1 misho 96: {
1.1.1.3 ! misho 97: /* NB, must not alter name if we return zero */
! 98: for (p = tail; *p; p++)
! 99: {
! 100: char c = *p;
! 101:
! 102: if ((c >='0' && c <= '9') || c == '-')
! 103: continue;
! 104:
! 105: if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
! 106: continue;
! 107:
! 108: break;
! 109: }
! 110:
! 111: if (*p != '.')
! 112: continue;
! 113:
! 114: *p = 0;
! 115:
! 116: if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail)
1.1 misho 117: {
1.1.1.3 ! misho 118: /* special hack for v4-mapped. */
! 119: memcpy(tail, "::ffff:", 7);
! 120: for (p = tail + 7; *p; p++)
! 121: if (*p == '-')
! 122: *p = '.';
1.1 misho 123: }
124: else
125: {
1.1.1.3 ! misho 126: /* swap . or : for - */
! 127: for (p = tail; *p; p++)
! 128: if (*p == '-')
! 129: {
! 130: if (prot == AF_INET)
! 131: *p = '.';
! 132: else
! 133: *p = ':';
! 134: }
! 135: }
! 136:
! 137: if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
! 138: {
! 139: if (prot == AF_INET)
! 140: {
! 141: if (!c->is6 &&
! 142: ntohl(addr->addr4.s_addr) >= ntohl(c->start.s_addr) &&
! 143: ntohl(addr->addr4.s_addr) <= ntohl(c->end.s_addr))
! 144: found = 1;
! 145: }
! 146: else
! 147: {
! 148: u64 addrpart = addr6part(&addr->addr6);
! 149:
! 150: if (c->is6 &&
! 151: is_same_net6(&addr->addr6, &c->start6, 64) &&
! 152: addrpart >= addr6part(&c->start6) &&
! 153: addrpart <= addr6part(&c->end6))
! 154: found = 1;
! 155: }
1.1 misho 156: }
1.1.1.3 ! misho 157:
1.1 misho 158: }
1.1.1.3 ! misho 159:
1.1 misho 160: /* restore name */
161: for (p = tail; *p; p++)
162: if (*p == '.' || *p == ':')
163: *p = '-';
164:
165: *p = '.';
1.1.1.3 ! misho 166:
! 167:
1.1 misho 168: if (found)
169: return 1;
170: }
171:
172: return 0;
173: }
174:
175:
1.1.1.3 ! misho 176: int is_rev_synth(int flag, union all_addr *addr, char *name)
1.1 misho 177: {
178: struct cond_domain *c;
179:
1.1.1.3 ! misho 180: if (flag & F_IPV4 && (c = search_domain(addr->addr4, daemon->synth_domains)))
1.1 misho 181: {
182: char *p;
183:
184: *name = 0;
1.1.1.3 ! misho 185: if (c->indexed)
! 186: {
! 187: unsigned int index = ntohl(addr->addr4.s_addr) - ntohl(c->start.s_addr);
! 188: snprintf(name, MAXDNAME, "%s%u", c->prefix ? c->prefix : "", index);
! 189: }
! 190: else
! 191: {
! 192: if (c->prefix)
! 193: strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
! 194:
! 195: inet_ntop(AF_INET, &addr->addr4, name + strlen(name), ADDRSTRLEN);
! 196: for (p = name; *p; p++)
! 197: if (*p == '.')
! 198: *p = '-';
! 199: }
1.1 misho 200:
201: strncat(name, ".", MAXDNAME);
202: strncat(name, c->domain, MAXDNAME);
203:
204: return 1;
205: }
206:
1.1.1.3 ! misho 207: if ((flag & F_IPV6) && (c = search_domain6(&addr->addr6, daemon->synth_domains)))
1.1 misho 208: {
209: char *p;
210:
211: *name = 0;
1.1.1.3 ! misho 212: if (c->indexed)
1.1 misho 213: {
1.1.1.3 ! misho 214: u64 index = addr6part(&addr->addr6) - addr6part(&c->start6);
! 215: snprintf(name, MAXDNAME, "%s%llu", c->prefix ? c->prefix : "", index);
1.1 misho 216: }
1.1.1.3 ! misho 217: else
! 218: {
! 219: if (c->prefix)
! 220: strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
! 221:
! 222: inet_ntop(AF_INET6, &addr->addr6, name + strlen(name), ADDRSTRLEN);
1.1 misho 223:
1.1.1.3 ! misho 224: /* IPv6 presentation address can start with ":", but valid domain names
! 225: cannot start with "-" so prepend a zero in that case. */
! 226: if (!c->prefix && *name == ':')
! 227: {
! 228: *name = '0';
! 229: inet_ntop(AF_INET6, &addr->addr6, name+1, ADDRSTRLEN);
! 230: }
! 231:
! 232: /* V4-mapped have periods.... */
! 233: for (p = name; *p; p++)
! 234: if (*p == ':' || *p == '.')
! 235: *p = '-';
! 236:
! 237: }
1.1 misho 238:
239: strncat(name, ".", MAXDNAME);
240: strncat(name, c->domain, MAXDNAME);
241:
242: return 1;
243: }
244:
245: return 0;
246: }
247:
248:
249: static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c)
250: {
251: for (; c; c = c->next)
252: if (!c->is6 &&
253: ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
254: ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
255: return c;
256:
257: return NULL;
258: }
259:
260: char *get_domain(struct in_addr addr)
261: {
262: struct cond_domain *c;
263:
264: if ((c = search_domain(addr, daemon->cond_domain)))
265: return c->domain;
266:
267: return daemon->domain_suffix;
268: }
269:
1.1.1.3 ! misho 270:
1.1 misho 271: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
272: {
273: u64 addrpart = addr6part(addr);
274:
275: for (; c; c = c->next)
276: if (c->is6 &&
277: is_same_net6(addr, &c->start6, 64) &&
278: addrpart >= addr6part(&c->start6) &&
279: addrpart <= addr6part(&c->end6))
280: return c;
281:
282: return NULL;
283: }
284:
285: char *get_domain6(struct in6_addr *addr)
286: {
287: struct cond_domain *c;
288:
289: if (addr && (c = search_domain6(addr, daemon->cond_domain)))
290: return c->domain;
291:
292: return daemon->domain_suffix;
293: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>