Warning when using --bind-interfaces and routeable addresses.
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 83d77d8..a2b37dc 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -632,6 +632,8 @@
 
   if (bind_fallback)
     my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
+
+  warn_bound_listeners();
   
   if (!option_bool(OPT_NOWILD)) 
     for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
@@ -856,6 +858,7 @@
 	  enumerate_interfaces(0);
 	  /* NB, is_dad_listeners() == 1 --> we're binding interfaces */
 	  create_bound_listeners(0);
+	  warn_bound_listeners();
 	}
 
 #ifdef HAVE_LINUX_NETWORK
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index adf0828..17a351f 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -454,7 +454,7 @@
 struct irec {
   union mysockaddr addr;
   struct in_addr netmask; /* only valid for IPv4 */
-  int tftp_ok, dhcp_ok, mtu, done, dad, dns_auth, index, multicast_done;
+  int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done;
   char *name; 
   struct irec *next;
 };
@@ -988,6 +988,7 @@
 int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, 
 		 char *name, int isExtract, int extrabytes);
 int in_arpa_name_2_addr(char *namein, struct all_addr *addrp);
+int private_net(struct in_addr addr, int ban_localhost);
 
 /* auth.c */
 #ifdef HAVE_AUTH
@@ -1068,6 +1069,7 @@
 int enumerate_interfaces(int reset);
 void create_wildcard_listeners(void);
 void create_bound_listeners(int die);
+void warn_bound_listeners(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 fc0346e..de5d9f2 100644
--- a/src/network.c
+++ b/src/network.c
@@ -16,6 +16,10 @@
 
 #include "dnsmasq.h"
 
+#ifndef IN6_IS_ADDR_ULA
+#define IN6_IS_ADDR_ULA(a) ((((__const uint32_t *) (a))[0] & htonl (0xfe00000)) == htonl (0xfc000000))
+#endif
+
 #ifdef HAVE_LINUX_NETWORK
 
 int indextoname(int fd, int index, char *name)
@@ -383,7 +387,7 @@
       iface->dns_auth = auth_dns;
       iface->mtu = mtu;
       iface->dad = dad;
-      iface->done = iface->multicast_done = 0;
+      iface->done = iface->multicast_done = iface->warned = 0;
       iface->index = if_index;
       if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
 	{
@@ -824,6 +828,59 @@
       }
 }
 
+/* In --bind-interfaces, the only access control is the addresses we're listening on. 
+   There's nothing to avoid a query to the address of an internal interface arriving via
+   an external interface where we don't want to accept queries, except that in the usual 
+   case the addresses of internal interfaces are RFC1918. When bind-interfaces in use, 
+   and we listen on an address that looks like it's probably globally routeable, shout.
+
+   The fix is to use --bind-dynamic, which actually checks the arrival interface too.
+   Tough if your platform doesn't support this.
+*/
+
+void warn_bound_listeners(void)
+{
+  struct irec *iface; 	
+  int advice = 0;
+
+  for (iface = daemon->interfaces; iface; iface = iface->next)
+    if (option_bool(OPT_NOWILD) && !iface->dns_auth)
+      {
+	int warn = 0;
+	if (iface->addr.sa.sa_family == AF_INET)
+	  {
+	    if (!private_net(iface->addr.in.sin_addr, 1))
+	      {
+		inet_ntop(AF_INET, &iface->addr.in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
+		warn = 1;
+	      }
+	  }
+#ifdef HAVE_IPV6
+	else
+	  {
+	    if (!IN6_IS_ADDR_LINKLOCAL(&iface->addr.in6.sin6_addr) &&
+		!IN6_IS_ADDR_SITELOCAL(&iface->addr.in6.sin6_addr) &&
+		!IN6_IS_ADDR_ULA(&iface->addr.in6.sin6_addr) &&
+		!IN6_IS_ADDR_LOOPBACK(&iface->addr.in6.sin6_addr))
+	      {
+		inet_ntop(AF_INET6, &iface->addr.in6.sin6_addr, daemon->addrbuff, ADDRSTRLEN);
+		warn = 1;
+	      }
+	  }
+#endif
+	if (warn)
+	  {
+	    iface->warned = advice = 1;
+	    my_syslog(LOG_WARNING, 
+		      _("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).")); 
+}
+
 int is_dad_listeners(void)
 {
   struct irec *iface;
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 655216e..573ec31 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -724,7 +724,7 @@
 }
 
 /* is addr in the non-globally-routed IP space? */ 
-static int private_net(struct in_addr addr, int ban_localhost) 
+int private_net(struct in_addr addr, int ban_localhost) 
 {
   in_addr_t ip_addr = ntohl(addr.s_addr);