diff options
-rw-r--r-- | man/dnsmasq.8 | 8 | ||||
-rw-r--r-- | src/dnsmasq.c | 5 | ||||
-rw-r--r-- | src/dnsmasq.h | 2 | ||||
-rw-r--r-- | src/network.c | 18 | ||||
-rw-r--r-- | src/option.c | 13 |
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; } |