Changes to update Tomato RAF.
[tomato.git] / release / src / router / dnsmasq / src / domain.c
blob821f769a448bfaa82352e32d78d19ce980e8661b
1 /* dnsmasq is Copyright (c) 2000-2013 Simon Kelley
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.
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.
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/>.
17 #include "dnsmasq.h"
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
26 int is_name_synthetic(int flags, char *name, struct all_addr *addr)
28 char *p;
29 struct cond_domain *c = NULL;
30 int prot = AF_INET;
32 #ifdef HAVE_IPV6
33 if (flags & F_IPV6)
34 prot = AF_INET6;
35 #endif
37 for (c = daemon->synth_domains; c; c = c->next)
39 int found = 0;
40 char *tail, *pref;
42 for (tail = name, pref = c->prefix; *tail != 0 && pref && *pref != 0; tail++, pref++)
44 unsigned int c1 = (unsigned char) *pref;
45 unsigned int c2 = (unsigned char) *tail;
47 if (c1 >= 'A' && c1 <= 'Z')
48 c1 += 'a' - 'A';
49 if (c2 >= 'A' && c2 <= 'Z')
50 c2 += 'a' - 'A';
52 if (c1 != c2)
53 break;
56 if (pref && *pref != 0)
57 continue; /* prefix match fail */
59 /* NB, must not alter name if we return zero */
60 for (p = tail; *p; p++)
62 char c = *p;
64 if ((c >='0' && c <= '9') || c == '-')
65 continue;
67 #ifdef HAVE_IPV6
68 if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
69 continue;
70 #endif
72 break;
75 if (*p != '.')
76 continue;
78 *p = 0;
80 /* swap . or : for - */
81 for (p = tail; *p; p++)
82 if (*p == '-')
84 if (prot == AF_INET)
85 *p = '.';
86 #ifdef HAVE_IPV6
87 else
88 *p = ':';
89 #endif
92 if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
94 if (prot == AF_INET)
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;
101 #ifdef HAVE_IPV6
102 else
104 u64 addrpart = addr6part(&addr->addr.addr6);
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;
112 #endif
115 /* restore name */
116 for (p = tail; *p; p++)
117 if (*p == '.' || *p == ':')
118 *p = '-';
120 *p = '.';
122 if (found)
123 return 1;
126 return 0;
130 int is_rev_synth(int flag, struct all_addr *addr, char *name)
132 struct cond_domain *c;
134 if (flag & F_IPV4 && (c = search_domain(addr->addr.addr4, daemon->synth_domains)))
136 char *p;
138 *name = 0;
139 if (c->prefix)
140 strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
142 inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
143 for (p = name; *p; p++)
144 if (*p == '.')
145 *p = '-';
147 strncat(name, ".", MAXDNAME);
148 strncat(name, c->domain, MAXDNAME);
150 return 1;
153 #ifdef HAVE_IPV6
154 if (flag & F_IPV6 && (c = search_domain6(&addr->addr.addr6, daemon->synth_domains)))
156 char *p;
158 *name = 0;
159 if (c->prefix)
160 strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
162 inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN);
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 == ':')
168 *name = '0';
169 inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
172 for (p = name; *p; p++)
173 if (*p == ':')
174 *p = '-';
176 strncat(name, ".", MAXDNAME);
177 strncat(name, c->domain, MAXDNAME);
179 return 1;
181 #endif
183 return 0;
187 static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c)
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;
195 return NULL;
198 char *get_domain(struct in_addr addr)
200 struct cond_domain *c;
202 if ((c = search_domain(addr, daemon->cond_domain)))
203 return c->domain;
205 return daemon->domain_suffix;
208 #ifdef HAVE_IPV6
209 static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
211 u64 addrpart = addr6part(addr);
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;
220 return NULL;
223 char *get_domain6(struct in6_addr *addr)
225 struct cond_domain *c;
227 if ((c = search_domain6(addr, daemon->cond_domain)))
228 return c->domain;
230 return daemon->domain_suffix;
232 #endif