diff -uNr dnsmasq-2.40/src/dnsmasq.h dnsmasq-2.40_stopdnsrebind/src/dnsmasq.h
--- dnsmasq-2.40/src/dnsmasq.h	2007-08-09 14:17:41.000000000 +0200
+++ dnsmasq-2.40_stopdnsrebind/src/dnsmasq.h	2007-10-20 16:57:31.000000000 +0200
@@ -146,6 +146,7 @@
 #define OPT_TFTP_NOBLOCK   (1<<27)
 #define OPT_LOG_OPTS       (1<<28)
 #define OPT_TFTP_APREF     (1<<29)
+#define OPT_STOPDNSREBIND  (1<<30)
 
 struct all_addr {
   union {
@@ -601,7 +602,7 @@
 size_t setup_reply(HEADER *header, size_t  qlen,
 		   struct all_addr *addrp, unsigned short flags,
 		   unsigned long local_ttl);
-void extract_addresses(HEADER *header, size_t qlen, char *namebuff, time_t now);
+int extract_addresses(HEADER *header, size_t qlen, char *namebuff, time_t now);
 size_t answer_request(HEADER *header, char *limit, size_t qlen,  
 		   struct in_addr local_addr, struct in_addr local_netmask, time_t now);
 int check_for_bogus_wildcard(HEADER *header, size_t qlen, char *name, 
diff -uNr dnsmasq-2.40/src/forward.c dnsmasq-2.40_stopdnsrebind/src/forward.c
--- dnsmasq-2.40/src/forward.c	2007-07-23 20:22:31.000000000 +0200
+++ dnsmasq-2.40_stopdnsrebind/src/forward.c	2007-10-20 15:43:08.000000000 +0200
@@ -399,7 +399,9 @@
 	  header->rcode = NOERROR;
 	}
       
-      extract_addresses(header, n, daemon->namebuff, now);
+      if (!extract_addresses(header, n, daemon->namebuff, now)) {
+      	return 0;
+      }
     }
   
   /* do this after extract_addresses. Ensure NODATA reply and remove
diff -uNr dnsmasq-2.40/src/option.c dnsmasq-2.40_stopdnsrebind/src/option.c
--- dnsmasq-2.40/src/option.c	2007-08-17 22:05:08.000000000 +0200
+++ dnsmasq-2.40_stopdnsrebind/src/option.c	2007-10-20 17:17:22.000000000 +0200
@@ -46,6 +46,7 @@
 #define LOPT_BANK      272
 #define LOPT_DHCP_HOST 273
 #define LOPT_APREF     274
+#define LOPT_STOPDNSREBIND     275
 
 #ifdef HAVE_GETOPT_LONG
 static const struct option opts[] =  
@@ -138,6 +139,7 @@
     {"dhcp-subscrid", 1, 0, LOPT_SUBSCR },
     {"interface-name", 1, 0, LOPT_INTNAME },
     {"dhcp-hostsfile", 1, 0, LOPT_DHCP_HOST },
+    {"stopdnsrebind", 0, 0, LOPT_STOPDNSREBIND },
     { NULL, 0, 0, 0 }
   };
 
@@ -175,6 +177,7 @@
   { LOPT_NOBLOCK,   OPT_TFTP_NOBLOCK },
   { LOPT_LOG_OPTS,  OPT_LOG_OPTS },
   { LOPT_APREF,     OPT_TFTP_APREF },
+  { LOPT_STOPDNSREBIND, OPT_STOPDNSREBIND },
   { 'v',            0},
   { 'w',            0},
   { 0, 0 }
@@ -268,6 +271,7 @@
   { "    --tftp-no-blocksize", gettext_noop("Disable the TFTP blocksize extension."), NULL },
   { "    --log-dhcp", gettext_noop("Extra logging for DHCP."), NULL },
   { "    --log-async[=<log lines>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL },
+  { "    --stop-dns-rebinding", gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL },
   { NULL, NULL, NULL }
 }; 
 
diff -uNr dnsmasq-2.40/src/rfc1035.c dnsmasq-2.40_stopdnsrebind/src/rfc1035.c
--- dnsmasq-2.40/src/rfc1035.c	2007-08-07 12:47:08.000000000 +0200
+++ dnsmasq-2.40_stopdnsrebind/src/rfc1035.c	2007-10-20 17:35:18.000000000 +0200
@@ -587,7 +587,7 @@
 /* Note that the following code can create CNAME chains that don't point to a real record,
    either because of lack of memory, or lack of SOA records.  These are treated by the cache code as 
    expired and cleaned out that way. */
-void extract_addresses(HEADER *header, size_t qlen, char *name, time_t now)
+int extract_addresses(HEADER *header, size_t qlen, char *name, time_t now)
 {
   unsigned char *p, *p1, *endrr;
   int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
@@ -614,8 +614,8 @@
       unsigned long cttl = ULONG_MAX, attl;
       
       if (!extract_name(header, qlen, &p, name, 1))
-	return; /* bad packet */
-           
+	return 0; /* bad packet */
+	           
       GETSHORT(qtype, p); 
       GETSHORT(qclass, p);
       
@@ -627,7 +627,7 @@
       if (qtype == T_PTR)
 	{ 
 	  int name_encoding = in_arpa_name_2_addr(name, &addr);
-	  
+	  	  
 	  if (!name_encoding)
 	    continue;
 
@@ -635,12 +635,12 @@
 	    {
 	    cname_loop:
 	      if (!(p1 = skip_questions(header, qlen)))
-		return;
+		return 0;
 	      
 	      for (j = ntohs(header->ancount); j != 0; j--) 
 		{
 		  if (!(res = extract_name(header, qlen, &p1, name, 0)))
-		    return; /* bad packet */
+		    return 0; /* bad packet */
 		  
 		  GETSHORT(aqtype, p1); 
 		  GETSHORT(aqclass, p1);
@@ -655,12 +655,12 @@
 		  if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
 		    {
 		      if (!extract_name(header, qlen, &p1, name, 1))
-			return;
+			return 0;
 		      
 		      if (aqtype == T_CNAME)
 			{
 			  if (!cname_count--)
-			    return; /* looped CNAMES */
+			    return 0; /* looped CNAMES */
 			  goto cname_loop;
 			}
 		      
@@ -670,7 +670,7 @@
 		  
 		  p1 = endrr;
 		  if ((size_t)(p1 - (unsigned char *)header) > qlen)
-		    return; /* bad packet */
+		    return 0; /* bad packet */
 		}
 	    }
 	  
@@ -710,12 +710,12 @@
 	    {
 	    cname_loop1:
 	      if (!(p1 = skip_questions(header, qlen)))
-		return;
+		return 0;
 	      
 	      for (j = ntohs(header->ancount); j != 0; j--) 
 		{
 		  if (!(res = extract_name(header, qlen, &p1, name, 0)))
-		    return; /* bad packet */
+		    return 0; /* bad packet */
 		  
 		  GETSHORT(aqtype, p1); 
 		  GETSHORT(aqclass, p1);
@@ -728,7 +728,8 @@
 		      if (aqtype == T_CNAME)
 			{
 			  if (!cname_count--)
-			    return; /* looped CNAMES */
+			    return 0; /* looped CNAMES */
+			    
 			  newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
 			  if (newc && cpp)
 			    {
@@ -741,7 +742,7 @@
 			    cttl = attl;
 			  
 			  if (!extract_name(header, qlen, &p1, name, 1))
-			    return;
+			    return 0;
 			  goto cname_loop1;
 			}
 		      else
@@ -749,19 +750,26 @@
 			  found = 1;
 			  /* copy address into aligned storage */
 			  memcpy(&addr, p1, addrlen);
+
+			  if ((daemon->options & OPT_STOPDNSREBIND) && private_net(addr.addr.addr4)) {
+			  	//printf("possible dns rebinding attack detected for %s -> %s\n", name, inet_ntoa(addr.addr.addr4));
+				return 0;
+			  }
+			  else {
 			  newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
 			  if (newc && cpp)
 			    {
 			      cpp->addr.cname.cache = newc;
 			      cpp->addr.cname.uid = newc->uid;
 			    }
+			   }
 			  cpp = NULL;
 			}
 		    }
 		  
 		  p1 = endrr;
 		  if ((size_t)(p1 - (unsigned char *)header) > qlen)
-		    return; /* bad packet */
+		    return 0; /* bad packet */
 		}
 	    }
 	  
@@ -788,6 +796,7 @@
     }
   
   cache_end_insert();
+  return 1;
 }
 
 /* If the packet holds exactly one query
