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/>.
20 static struct cond_domain
*search_domain(struct in_addr addr
, struct cond_domain
*c
);
22 static struct cond_domain
*search_domain6(struct in6_addr
*addr
, struct cond_domain
*c
);
26 int is_name_synthetic(int flags
, char *name
, struct all_addr
*addr
)
29 struct cond_domain
*c
= NULL
;
37 for (c
= daemon
->synth_domains
; c
; c
= c
->next
)
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')
49 if (c2
>= 'A' && c2
<= 'Z')
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
++)
64 if ((c
>='0' && c
<= '9') || c
== '-')
68 if (prot
== AF_INET6
&& ((c
>='A' && c
<= 'F') || (c
>='a' && c
<= 'f')))
80 /* swap . or : for - */
81 for (p
= tail
; *p
; p
++)
92 if (hostname_isequal(c
->domain
, p
+1) && inet_pton(prot
, tail
, addr
))
97 ntohl(addr
->addr
.addr4
.s_addr
) >= ntohl(c
->start
.s_addr
) &&
98 ntohl(addr
->addr
.addr4
.s_addr
) <= ntohl(c
->end
.s_addr
))
104 u64 addrpart
= addr6part(&addr
->addr
.addr6
);
107 is_same_net6(&addr
->addr
.addr6
, &c
->start6
, 64) &&
108 addrpart
>= addr6part(&c
->start6
) &&
109 addrpart
<= addr6part(&c
->end6
))
116 for (p
= tail
; *p
; p
++)
117 if (*p
== '.' || *p
== ':')
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
)))
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
++)
147 strncat(name
, ".", MAXDNAME
);
148 strncat(name
, c
->domain
, MAXDNAME
);
154 if (flag
& F_IPV6
&& (c
= search_domain6(&addr
->addr
.addr6
, daemon
->synth_domains
)))
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
== ':')
169 inet_ntop(AF_INET6
, &addr
->addr
.addr6
, name
+1, ADDRSTRLEN
);
172 for (p
= name
; *p
; p
++)
176 strncat(name
, ".", MAXDNAME
);
177 strncat(name
, c
->domain
, MAXDNAME
);
187 static struct cond_domain
*search_domain(struct in_addr addr
, struct cond_domain
*c
)
189 for (; c
; c
= c
->next
)
191 ntohl(addr
.s_addr
) >= ntohl(c
->start
.s_addr
) &&
192 ntohl(addr
.s_addr
) <= ntohl(c
->end
.s_addr
))
198 char *get_domain(struct in_addr addr
)
200 struct cond_domain
*c
;
202 if ((c
= search_domain(addr
, daemon
->cond_domain
)))
205 return daemon
->domain_suffix
;
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
)
215 is_same_net6(addr
, &c
->start6
, 64) &&
216 addrpart
>= addr6part(&c
->start6
) &&
217 addrpart
<= addr6part(&c
->end6
))
223 char *get_domain6(struct in6_addr
*addr
)
225 struct cond_domain
*c
;
227 if ((c
= search_domain6(addr
, daemon
->cond_domain
)))
230 return daemon
->domain_suffix
;