Return to domain.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src |
1.1.1.2 ! misho 1: /* dnsmasq is Copyright (c) 2000-2016 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: #ifdef HAVE_IPV6
22: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
23: #endif
24:
25:
26: int is_name_synthetic(int flags, char *name, struct all_addr *addr)
27: {
28: char *p;
29: struct cond_domain *c = NULL;
30: int prot = AF_INET;
31:
32: #ifdef HAVE_IPV6
33: if (flags & F_IPV6)
34: prot = AF_INET6;
35: #endif
36:
37: for (c = daemon->synth_domains; c; c = c->next)
38: {
39: int found = 0;
40: char *tail, *pref;
41:
42: for (tail = name, pref = c->prefix; *tail != 0 && pref && *pref != 0; tail++, pref++)
43: {
44: unsigned int c1 = (unsigned char) *pref;
45: unsigned int c2 = (unsigned char) *tail;
46:
47: if (c1 >= 'A' && c1 <= 'Z')
48: c1 += 'a' - 'A';
49: if (c2 >= 'A' && c2 <= 'Z')
50: c2 += 'a' - 'A';
51:
52: if (c1 != c2)
53: break;
54: }
55:
56: if (pref && *pref != 0)
57: continue; /* prefix match fail */
58:
59: /* NB, must not alter name if we return zero */
60: for (p = tail; *p; p++)
61: {
62: char c = *p;
63:
64: if ((c >='0' && c <= '9') || c == '-')
65: continue;
66:
67: #ifdef HAVE_IPV6
68: if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
69: continue;
70: #endif
71:
72: break;
73: }
74:
75: if (*p != '.')
76: continue;
77:
78: *p = 0;
79:
80: /* swap . or : for - */
81: for (p = tail; *p; p++)
82: if (*p == '-')
83: {
84: if (prot == AF_INET)
85: *p = '.';
86: #ifdef HAVE_IPV6
87: else
88: *p = ':';
89: #endif
90: }
91:
92: if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
93: {
94: if (prot == AF_INET)
95: {
96: if (!c->is6 &&
97: ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) &&
98: ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr))
99: found = 1;
100: }
101: #ifdef HAVE_IPV6
102: else
103: {
104: u64 addrpart = addr6part(&addr->addr.addr6);
105:
106: if (c->is6 &&
107: is_same_net6(&addr->addr.addr6, &c->start6, 64) &&
108: addrpart >= addr6part(&c->start6) &&
109: addrpart <= addr6part(&c->end6))
110: found = 1;
111: }
112: #endif
113: }
114:
115: /* restore name */
116: for (p = tail; *p; p++)
117: if (*p == '.' || *p == ':')
118: *p = '-';
119:
120: *p = '.';
121:
122: if (found)
123: return 1;
124: }
125:
126: return 0;
127: }
128:
129:
130: int is_rev_synth(int flag, struct all_addr *addr, char *name)
131: {
132: struct cond_domain *c;
133:
134: if (flag & F_IPV4 && (c = search_domain(addr->addr.addr4, daemon->synth_domains)))
135: {
136: char *p;
137:
138: *name = 0;
139: if (c->prefix)
140: strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
141:
142: inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
143: for (p = name; *p; p++)
144: if (*p == '.')
145: *p = '-';
146:
147: strncat(name, ".", MAXDNAME);
148: strncat(name, c->domain, MAXDNAME);
149:
150: return 1;
151: }
152:
153: #ifdef HAVE_IPV6
154: if (flag & F_IPV6 && (c = search_domain6(&addr->addr.addr6, daemon->synth_domains)))
155: {
156: char *p;
157:
158: *name = 0;
159: if (c->prefix)
160: strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
161:
162: inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN);
163:
164: /* IPv6 presentation address can start with ":", but valid domain names
165: cannot start with "-" so prepend a zero in that case. */
166: if (!c->prefix && *name == ':')
167: {
168: *name = '0';
169: inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
170: }
171:
172: for (p = name; *p; p++)
173: if (*p == ':')
174: *p = '-';
175:
176: strncat(name, ".", MAXDNAME);
177: strncat(name, c->domain, MAXDNAME);
178:
179: return 1;
180: }
181: #endif
182:
183: return 0;
184: }
185:
186:
187: static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c)
188: {
189: for (; c; c = c->next)
190: if (!c->is6 &&
191: ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
192: ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
193: return c;
194:
195: return NULL;
196: }
197:
198: char *get_domain(struct in_addr addr)
199: {
200: struct cond_domain *c;
201:
202: if ((c = search_domain(addr, daemon->cond_domain)))
203: return c->domain;
204:
205: return daemon->domain_suffix;
206: }
207:
208: #ifdef HAVE_IPV6
209: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
210: {
211: u64 addrpart = addr6part(addr);
212:
213: for (; c; c = c->next)
214: if (c->is6 &&
215: is_same_net6(addr, &c->start6, 64) &&
216: addrpart >= addr6part(&c->start6) &&
217: addrpart <= addr6part(&c->end6))
218: return c;
219:
220: return NULL;
221: }
222:
223: char *get_domain6(struct in6_addr *addr)
224: {
225: struct cond_domain *c;
226:
227: if (addr && (c = search_domain6(addr, daemon->cond_domain)))
228: return c->domain;
229:
230: return daemon->domain_suffix;
231: }
232: #endif