Commit f7029f5c authored by Simon Kelley's avatar Simon Kelley

Extend /4 and /6 syntax to --interface-name

parent c50f25a3
...@@ -514,11 +514,13 @@ record (which is always in the C_IN class). The value of the record is ...@@ -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 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. 012345 or any mixture of these.
.TP .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 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 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 down, not configured or non-existent, an empty record is returned. The
matching PTR record is also created, mapping the interface address to matching PTR record is also created, mapping the interface address to
the name. More than one name may be associated with an interface the name. More than one name may be associated with an interface
......
...@@ -636,7 +636,10 @@ int main (int argc, char **argv) ...@@ -636,7 +636,10 @@ int main (int argc, char **argv)
if (bind_fallback) if (bind_fallback)
my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations")); 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)) if (!option_bool(OPT_NOWILD))
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next) for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
......
...@@ -321,6 +321,7 @@ struct host_record { ...@@ -321,6 +321,7 @@ struct host_record {
struct interface_name { struct interface_name {
char *name; /* domain name */ char *name; /* domain name */
char *intr; /* interface name */ char *intr; /* interface name */
int family; /* AF_INET, AF_INET6 or zero for both */
struct addrlist *addr; struct addrlist *addr;
struct interface_name *next; struct interface_name *next;
}; };
...@@ -1076,6 +1077,7 @@ int enumerate_interfaces(int reset); ...@@ -1076,6 +1077,7 @@ int enumerate_interfaces(int reset);
void create_wildcard_listeners(void); void create_wildcard_listeners(void);
void create_bound_listeners(int die); void create_bound_listeners(int die);
void warn_bound_listeners(void); void warn_bound_listeners(void);
void warn_int_names(void);
int is_dad_listeners(void); int is_dad_listeners(void);
int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns); 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); int loopback_exception(int fd, int family, struct all_addr *addr, char *name);
......
...@@ -330,7 +330,8 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label, ...@@ -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 /* Update addresses from interface_names. These are a set independent
of the set we're listening on. */ of the set we're listening on. */
for (int_name = daemon->int_names; int_name; int_name = int_name->next) 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) if (param->spare)
{ {
...@@ -915,7 +916,7 @@ void warn_bound_listeners(void) ...@@ -915,7 +916,7 @@ void warn_bound_listeners(void)
int advice = 0; int advice = 0;
for (iface = daemon->interfaces; iface; iface = iface->next) for (iface = daemon->interfaces; iface; iface = iface->next)
if (option_bool(OPT_NOWILD) && !iface->dns_auth) if (!iface->dns_auth)
{ {
int warn = 0; int warn = 0;
if (iface->addr.sa.sa_family == AF_INET) if (iface->addr.sa.sa_family == AF_INET)
...@@ -943,15 +944,24 @@ void warn_bound_listeners(void) ...@@ -943,15 +944,24 @@ void warn_bound_listeners(void)
{ {
iface->warned = advice = 1; iface->warned = advice = 1;
my_syslog(LOG_WARNING, 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); daemon->addrbuff, iface->name);
} }
} }
if (advice) 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) int is_dad_listeners(void)
{ {
struct irec *iface; struct irec *iface;
......
...@@ -3376,6 +3376,19 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma ...@@ -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)); for (up = &daemon->int_names; *up; up = &((*up)->next));
*up = new; *up = new;
new->name = domain; 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); new->intr = opt_string_alloc(comma);
break; break;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment