Teach --bogus-nxdomain and --ignore-address to take a subnet argument.
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index e201b7a..20d687a 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -325,7 +325,7 @@
 
 
 struct bogus_addr {
-  struct in_addr addr;
+  struct in_addr addr, mask;
   struct bogus_addr *next;
 };
 
@@ -1241,8 +1241,8 @@
 		      struct in_addr local_addr, struct in_addr local_netmask, 
 		      time_t now, int ad_reqd, int do_bit, int have_pseudoheader);
 int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, 
-			     struct bogus_addr *baddr, time_t now);
-int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr);
+			     time_t now);
+int check_for_ignored_address(struct dns_header *header, size_t qlen);
 int check_for_local_domain(char *name, time_t now);
 size_t resize_packet(struct dns_header *header, size_t plen, 
 		  unsigned char *pheader, size_t hlen);
diff --git a/src/forward.c b/src/forward.c
index 6bbf8a4..0ea829c 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -738,7 +738,7 @@
     }  
 
   if (daemon->bogus_addr && rcode != NXDOMAIN &&
-      check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
+      check_for_bogus_wildcard(header, n, daemon->namebuff, now))
     {
       munged = 1;
       SET_RCODE(header, NXDOMAIN);
@@ -866,7 +866,7 @@
   daemon->log_source_addr = &forward->frec_src.source;
   
   if (daemon->ignore_addr && RCODE(header) == NOERROR &&
-      check_for_ignored_address(header, n, daemon->ignore_addr))
+      check_for_ignored_address(header, n))
     return;
 
   /* Note: if we send extra options in the EDNS0 header, we can't recreate
diff --git a/src/option.c b/src/option.c
index bfda212..b6ab7ce 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2487,8 +2487,14 @@
     case LOPT_IGNORE_ADDR: /* --ignore-address */
      {
 	struct in_addr addr;
+	int prefix = 32;
 	unhide_metas(arg);
-	if (arg && (inet_pton(AF_INET, arg, &addr) > 0))
+
+	if (!arg ||
+	    ((comma = split_chr(arg, '/')) && !atoi_check(comma, &prefix)) ||
+	    (inet_pton(AF_INET, arg, &addr) != 1))
+	  ret_err(gen_err); /* error */
+	else
 	  {
 	    struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));
 	    if (option == 'B')
@@ -2501,12 +2507,11 @@
 		baddr->next = daemon->ignore_addr;
 		daemon->ignore_addr = baddr;
 	      }
-	    baddr->addr = addr;
+	    baddr->mask.s_addr = htonl(~((1 << (32 - prefix)) - 1));
+	    baddr->addr.s_addr = addr.s_addr & baddr->mask.s_addr;
 	  }
-	else
-	  ret_err(gen_err); /* error */
-	break;	
-      }
+	break;
+     }
       
     case 'a':  /* --listen-address */
     case LOPT_AUTHPEER: /* --auth-peer */
diff --git a/src/rfc1035.c b/src/rfc1035.c
index ea438c2..5a961b8 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1017,30 +1017,33 @@
   return 0;
 }
 
-/* Is the packet a reply with the answer address equal to addr?
-   If so mung is into an NXDOMAIN reply and also put that information
-   in the cache. */
-int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, 
-			     struct bogus_addr *baddr, time_t now)
+static int check_bad_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr, char *name, unsigned long *ttlp)
 {
   unsigned char *p;
   int i, qtype, qclass, rdlen;
   unsigned long ttl;
   struct bogus_addr *baddrp;
-
+  struct in_addr addr;
+  
   /* skip over questions */
   if (!(p = skip_questions(header, qlen)))
     return 0; /* bad packet */
 
   for (i = ntohs(header->ancount); i != 0; i--)
     {
-      if (!extract_name(header, qlen, &p, name, 1, 10))
+      if (name && !extract_name(header, qlen, &p, name, 1, 10))
 	return 0; /* bad packet */
-  
+
+      if (!name && !(p = skip_name(p, header, qlen, 10)))
+	return 0;
+      
       GETSHORT(qtype, p); 
       GETSHORT(qclass, p);
       GETLONG(ttl, p);
       GETSHORT(rdlen, p);
+
+      if (ttlp)
+	*ttlp = ttl;
       
       if (qclass == C_IN && qtype == T_A)
 	{
@@ -1048,16 +1051,12 @@
 	    return 0;
 	  
 	  for (baddrp = baddr; baddrp; baddrp = baddrp->next)
-	    if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
-	      {
-		/* Found a bogus address. Insert that info here, since there no SOA record
-		   to get the ttl from in the normal processing */
-		cache_start_insert();
-		cache_insert(name, NULL, C_IN, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
-		cache_end_insert();
-		
+	    {
+	      memcpy(&addr, p, INADDRSZ);
+	      
+	      if ((addr.s_addr & baddrp->mask.s_addr) == baddrp->addr.s_addr)
 		return 1;
-	      }
+	    }
 	}
       
       if (!ADD_RDLEN(header, p, qlen, rdlen))
@@ -1067,43 +1066,31 @@
   return 0;
 }
 
-int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr)
+/* Is the packet a reply with the answer address equal to addr?
+   If so mung is into an NXDOMAIN reply and also put that information
+   in the cache. */
+int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, time_t now)
 {
-  unsigned char *p;
-  int i, qtype, qclass, rdlen;
-  struct bogus_addr *baddrp;
+  unsigned long ttl;
 
-  /* skip over questions */
-  if (!(p = skip_questions(header, qlen)))
-    return 0; /* bad packet */
-
-  for (i = ntohs(header->ancount); i != 0; i--)
+  if (check_bad_address(header, qlen, daemon->bogus_addr, name, &ttl))
     {
-      if (!(p = skip_name(p, header, qlen, 10)))
-	return 0; /* bad packet */
-      
-      GETSHORT(qtype, p); 
-      GETSHORT(qclass, p);
-      p += 4; /* TTL */
-      GETSHORT(rdlen, p);
-      
-      if (qclass == C_IN && qtype == T_A)
-	{
-	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
-	    return 0;
-	  
-	  for (baddrp = baddr; baddrp; baddrp = baddrp->next)
-	    if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
-	      return 1;
-	}
-      
-      if (!ADD_RDLEN(header, p, qlen, rdlen))
-	return 0;
+      /* Found a bogus address. Insert that info here, since there no SOA record
+	 to get the ttl from in the normal processing */
+      cache_start_insert();
+      cache_insert(name, NULL, C_IN, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
+      cache_end_insert();
+
+      return 1;
     }
-  
+
   return 0;
 }
 
+int check_for_ignored_address(struct dns_header *header, size_t qlen)
+{
+  return check_bad_address(header, qlen, daemon->ignore_addr, NULL, NULL);
+}
 
 int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp, 
 			unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)