summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Kelley <simon@thekelleys.org.uk>2013-11-21 15:09:09 +0000
committerSimon Kelley <simon@thekelleys.org.uk>2013-11-21 15:10:02 +0000
commitf7029f5c0887f81be3a7e3721eea2b247f00e0b7 (patch)
tree47d581ec0aeecb6403da1ce0b4cd3cb96a720e4b
parentc50f25a3ea4bced5318e59fb1bcc5ca968a4d3af (diff)
downloaddnsmasq-2.68rc1.tar.gz
Extend /4 and /6 syntax to --interface-namev2.68rc1
-rw-r--r--man/dnsmasq.88
-rw-r--r--src/dnsmasq.c5
-rw-r--r--src/dnsmasq.h2
-rw-r--r--src/network.c18
-rw-r--r--src/option.c13
5 files changed, 38 insertions, 8 deletions
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index 9a8de1f..049f664 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -514,11 +514,13 @@ record (which is always in the C_IN class). The value of the record is
given by the hex data, which may be of the form 01:23:45 or 01 23 45 or
012345 or any mixture of these.
.TP
-.B --interface-name=<name>,<interface>
+.B --interface-name=<name>,<interface>[/4|/6]
Return a DNS record associating the name with the primary address on
-the given interface. This flag specifies an A record for the given
+the given interface. This flag specifies an A or AAAA record for the given
name in the same way as an /etc/hosts line, except that the address is
-not constant, but taken from the given interface. If the interface is
+not constant, but taken from the given interface. The interface may be
+followed by "/4" or "/6" to specify that only IPv4 or IPv6 addresses
+of the interface should be used. If the interface is
down, not configured or non-existent, an empty record is returned. The
matching PTR record is also created, mapping the interface address to
the name. More than one name may be associated with an interface
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index a701ab5..4c8cf8a 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -636,7 +636,10 @@ int main (int argc, char **argv)
if (bind_fallback)
my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
- warn_bound_listeners();
+ if (option_bool(OPT_NOWILD))
+ warn_bound_listeners();
+
+ warn_int_names();
if (!option_bool(OPT_NOWILD))
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index c316b50..5efa7ad 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -321,6 +321,7 @@ struct host_record {
struct interface_name {
char *name; /* domain name */
char *intr; /* interface name */
+ int family; /* AF_INET, AF_INET6 or zero for both */
struct addrlist *addr;
struct interface_name *next;
};
@@ -1076,6 +1077,7 @@ int enumerate_interfaces(int reset);
void create_wildcard_listeners(void);
void create_bound_listeners(int die);
void warn_bound_listeners(void);
+void warn_int_names(void);
int is_dad_listeners(void);
int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns);
int loopback_exception(int fd, int family, struct all_addr *addr, char *name);
diff --git a/src/network.c b/src/network.c
index 51d9d53..5454d31 100644
--- a/src/network.c
+++ b/src/network.c
@@ -330,7 +330,8 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
/* Update addresses from interface_names. These are a set independent
of the set we're listening on. */
for (int_name = daemon->int_names; int_name; int_name = int_name->next)
- if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0)
+ if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0 &&
+ (addr->sa.sa_family == int_name->family || int_name->family == 0))
{
if (param->spare)
{
@@ -915,7 +916,7 @@ void warn_bound_listeners(void)
int advice = 0;
for (iface = daemon->interfaces; iface; iface = iface->next)
- if (option_bool(OPT_NOWILD) && !iface->dns_auth)
+ if (!iface->dns_auth)
{
int warn = 0;
if (iface->addr.sa.sa_family == AF_INET)
@@ -943,15 +944,24 @@ void warn_bound_listeners(void)
{
iface->warned = advice = 1;
my_syslog(LOG_WARNING,
- _("LOUD WARNING: listening on %s may accept requests via interfaces other than %s. "),
+ _("LOUD WARNING: listening on %s may accept requests via interfaces other than %s"),
daemon->addrbuff, iface->name);
}
}
if (advice)
- my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)."));
+ my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"));
}
+void warn_int_names(void)
+{
+ struct interface_name *intname;
+
+ for (intname = daemon->int_names; intname; intname = intname->next)
+ if (!intname->addr)
+ my_syslog(LOG_WARNING, _("warning: no addresses found for interface %s"), intname->intr);
+}
+
int is_dad_listeners(void)
{
struct irec *iface;
diff --git a/src/option.c b/src/option.c
index 6ccf4b1..89912e3 100644
--- a/src/option.c
+++ b/src/option.c
@@ -3376,6 +3376,19 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
for (up = &daemon->int_names; *up; up = &((*up)->next));
*up = new;
new->name = domain;
+ new->family = 0;
+ arg = split_chr(comma, '/');
+ if (arg)
+ {
+ if (strcmp(arg, "4") == 0)
+ new->family = AF_INET;
+#ifdef HAVE_IPV6
+ else if (strcmp(arg, "6") == 0)
+ new->family = AF_INET6;
+#endif
+ else
+ ret_err(gen_err);
+ }
new->intr = opt_string_alloc(comma);
break;
}