-- the ranges we want to receive redirect instead of NXDOMAIN
nxrranges={
        "127.0.0.0/24",         -- debug
		"4.0.0.0/8",			-- just an example CIDR range
}
-- the ranges we want to count differently
nxrranges_dialin={
        "127.0.0.0/24",         -- debug
		"8.0.0.0/8",			-- just an example CIDR range
}
nxr_stat_full_match=0
nxr_stat_full_match_dialin=0
nxr_stat_suffix_exclude=0
nxr_stat_suffix_exclude_dialin=0
nxr_stat_suffix_match=0
nxr_stat_suffix_match_dialin=0
nxr_stat_prefix_exclude=0
nxr_stat_prefix_exclude_dialin=0
nxr_stat_prefix_match=0
nxr_stat_prefix_match_dialin=0
nxr={
	-- services or folks that don't need or want to be redirected
	["suffix-excludes"]={
		"samsung%.router",
		"fritz%.box",
		"ttmails",
		"www%.free4people%.net",
		"nmextensions%.com",
		"oray%.net",
		"aa%.myleftnut%.info",
		"kusik%-tusik%.com",
		"damnedqueen%.name",
		"stopwatchingme%.name",
		"l33t%.freeshellz%.org",
		"msdos%.service%.security32%.com",
		"www%.free8%.biz",
		"for%.dawnsoul%.net",
		"ip%.dus%.net",
		"flamersunited%.info",
		"utils%.winfixer%.com",
		"haloservers%.bwserver%.biz",
		"getsome%.minilauncher%.net",
		"new%.antix%.us",
		"maps%-1%.biz",
		"badurl%.grandstreetinteractive%.com",
		"fuzion%.zerocore%.net",
		"john%.free4people%.net",
		"st0ned%.gh0stcon%.com",
		"2%.felony%-productions%.net",
		"nathan%.stjohnspark%.net",
		"server%.zuhause%.xx",
		"imageshack%.us",
		"yimg%.com",
		"photobucket%.com",
		"advertising%.com",
		"doubleclick%.net",
		"ivwbox%.de",
		"2mdn%.net",
		"atdmt%.com",
		"staging%.p2phub%.clipgenie%.com",
		"google%.omgitskp%.us",
		"lucy%.corp%.netopia%.com",
		"collect%.bearshare%.com",
		"listen%.aydankaya%.org",
		"lords%.aydankaya%.org",
		"updaterservice%.wildtangent%.com",
		"stopcollect%.bearshare%.com",
		"nymf0%.freed0m%.us",
		"update%.ch0de%.info",
		"phish%.mcafee%.com",
		"stage%.broder%.com",
		"gs%.gator%.com",
		"time%.chttl%.com%.tw",
		"usimage%.bounceme%.net",
		"bots%.acidirc%.net",
		"netli%.media%.adrevolver%.com",
		"ad%.infinite%-ads%.com",
		"bk%.vbulettin%.com",
		"bk%.ch0dewaffles%.info",
		"loot%.alumnigroup%.org",
		"nullspaz%.info",
		"div%.svc%.accenture%.com",
		"www%.olatesuite%.com",
		"www%.opasoft%.com",
		"www%.4ws%.com%.br",
		"www%.woai117%.cn",
		-- DNS RBLs start
		"0spam%.fusionzero%.com",
		"3y%.spam%.mrs%.kithrup%.com",
		"ab%.surbl%.org",
		"access%.redhawk%.org",
		"adv%.rhs%.mailpolice%.com",
		"ahbl%.org",
		"all%.spamblock%.unit%.liu%.se",
		"asiaspam%.spamblocked%.com",
		"black%.dnsbl%.securityplanet%.nl",
		"blackholes%.alphanet%.ch",
		"blackhole%.securitysage%.com",
		"blackhole%.cantv%.net",
		"blackholes%.five%-ten%-sg%.com",
		"blackholes%.uceb%.org",
		"blacklist%.hostkarma%.com",
		"blacklist%.sci%.kun%.nl",
		"blacklist%.sequoia%.ops%.asp%.att%.net",
		"blacklist%.woody%.ch",
		"bl%.csma%.biz",
		"bl%.deadbeef%.com",
		"bl%.emailbasura%.org",
		"bl%.gweep%.ca",
		"bl%.spamcop%.net",
		"bl%.open%-whois%.org",
		"bl%.redhatgate%.com",
		"bl%.spamcannibal%.org",
		"bl%.spamcop%.net",
		"bl%.starloop%.com",
		"bl%.technovision%.dk",
		"bl%.testrbl%.cameldns%.com",
		"blocked%.asgardnet%.org",
		"blocked%.hilli%.dk",
		"blocked%.secnap%.net",
		"block%.rhs%.mailpolice%.com",
		"bogons%.cymru%.com",
		"bsb%.spamlookup%.net",
		"bulk%.rhs%.mailpolice%.com",
		"c10%.rbl%.hk",
		"cabal%.web%-o%-trust%.org",
		"cbl%.abuseat%.org",
		"cbl%.anti%-spam%.org%.cn",
		"cblless%.anti%-spam%.org%.cn",
		"cblplus%.anti%-spam%.org%.cn",
		"cdl%.anti%-spam%.org%.cn",
		"cml%.anti%-spam%.org%.cn",
		"combined%.abuse%.ch",
		"db%.rurbl%.ru",
		"db%.wpbl%.info",
		"dialups%.mail%-abuse%.org",
		"dnsbl%.abuse%.ch",
		"dnsbl%.ahbl%.org",
		"dnsbl%.antispam%.or%.id",
		"dnsbl%.clue%-by%-4%.org",
		"dnsbl%.cyberlogic%.net",
		"dnsbl%.httpbl%.org",
		"dnsbl%.isoc%.bg",
		"dnsbl%.jammconsulting%.com",
		"dnsbl%.kempt%.net",
		"dnsbl%.mags%.net",
		"dnsbl%.mcu%.edu%.tw",
		"dnsbl%.njabl%.org",
		"dnsbl%.othello%.ch",
		"dnsbl%.sectoor%.de",
		"dnsbl%.solid%.net",
		"sorbs%.net",
		"dnsrbl%.swinog%.ch",
		"dnswl%.isoc%.bg",
		"dob%.sibl%.support%-intelligence%.net",
		"drone%.abuse%.ch",
		"dsbl%.dnsbl%.net%.au",
		"dsbl%.org",
		"duinv%.aupads%.org",
		"dul%.ru",
		"dynamic%.rhs%.mailpolice%.com",
		"dyna%.spamrats%.com",
		"dyn%.dnsbl%.epaxsys%.net",
		"dyndns%.rbl%.jp",
		"dynip%.rothen%.com",
		"eurospam%.spamblocked%.com",
		"exemptions%.ahbl%.org",
		"fl%.chickenboner%.biz",
		"flowgoaway%.com",
		"fnrbl%.fast%.net",
		"forbidden%.icm%.edu%.pl",
		"fraud%.rhs%.mailpolice%.com",
		"hardcore%.rbl%.sns%.ro",
		"hil%.habeas%.com",
		"hostkarma%.junkemailfilter%.com",
		"iadb2%.isipp%.com",
		"iadb%.isipp%.com",
		"iddb%.isipp%.com",
		"in%.dnsbl%.org",
		"in%-addr%.arpa",
		"intercept%.datapacket%.net",
		"ips%.backscatterer%.org",
		"ipv4%.fahq2%.com",
		"isps%.spamblocked%.com",
		"korea%.services%.net",
		"ksi%.dnsbl%.net%.au",
		"lacnic%.spamblocked%.com",
		"list%.dnswl%.org",
		"blacklist%.jippg%.org",
		"mail%.people%.it",
		"map%.spam%-rbl%.com",
		"multi%.surbl%.org",
		"dnsbl%.bit%.nl",
		"nml%.mail%-abuse%.org",
		"nofalsenegative%.stopspam%.samspade%.org",
		"nofalsepositive%.stopspam%.samspade%.org",
		"no%-more%-funn%.moensted%.dk",
		"noptr%.spamrats%.com",
		"ob%.surbl%.org",
		"ohps%.dnsbl%.net%.au",
		"omrs%.dnsbl%.net%.au",
		"orid%.dnsbl%.net%.au",
		"orvedb%.aupads%.org",
		"osps%.dnsbl%.net%.au",
		"osrs%.dnsbl%.net%.au",
		"owfs%.dnsbl%.net%.au",
		"owps%.dnsbl%.net%.au",
		"ph%.surbl%.org",
		"pool%.dnsbl%.solid%.net",
		"porn%.rhs%.mailpolice%.com",
		"ppbl%.beat%.st",
		"probes%.dnsbl%.net%.au",
		"proxy%.block%.transip%.nl",
		"psbl%.surriel%.com",
		"query%.bondedsender%.org",
		"query%.senderbase%.org",
		"rbl%.arix%.com",
		"rbl%.cbn%.net%.id",
		"rbl%.interserver%.net",
		"rbl%.msrbl%.net",
		"rbl%.orbitrbl%.com",
		"rbl%-plus%.mail%-abuse%.org",
		"rbl%.snark%.net",
		"rddn%.dnsbl%.net%.au",
		"rdts%.dnsbl%.net%.au",
		"relays%.bl%.kundenserver%.de",
		"relays%.mail%-abuse%.org",
		"relays%.nether%.net",
		"residential%.block%.transip%.nl",
		"rfc%-ignorant%.org",
		"rhsbl%.ahbl%.org",
		"ricn%.dnsbl%.net%.au",
		"rmst%.dnsbl%.net%.au",
		"rsbl%.aupads%.org",
		"sbbl%.they%.com",
		"sbl%.2stepback%.dk",
		"sbl%.csma%.biz",
		"sc%.surbl%.org",
		"short%.rbl%.jp",
		"softcore%.rbl%.sns%.ro",
		"sorbs%.dnsbl%.net%.au",
		"spamdomain%.block%.transip%.nl",
		"spamguard%.leadmon%.net",
		"spamhaus%.org",
		"spamlist%.or%.kr",
		"spamrats%.com",
		"spamrbl%.imp%.ch",
		"spamsites%.dnsbl%.net%.au",
		"spamsource%.block%.transip%.nl",
		"spamsources%.dnsbl%.info",
		"spamsources%.spamblocked%.com",
		"spam%.spamrats%.com",
		"spamtrap%.drbl%.drand%.net",
		"spam%.wytnij%.to",
		"spf%.trusted%-forwarder%.org",
		"stale%.sa_slip%.arix%.com",
		"t1%.bl%.dnsbl%.net%.au",
		"t3direct%.dnsbl%.net%.au",
		"test%.blocklist%.org",
		"tor%.ahbl%.org",
		"ucepn%.dnsbl%.net%.au",
		"uceprotect%.net",
		"unsure%.nether%.net",
		"uribl%.swinog%.ch",
		"url%.rbl%.jp",
		"virbl%.bit%.nl",
		"virus%.rbl%.jp",
		"vsnl%.net%.in",
		"wadb%.isipp%.com",
		"webmail%.rhs%.mailpolice%.com",
		"whitelist%.sci%.kun%.nl",
		"whitelist%.spamblocked%.com",
		"wormrbl%.imp%.ch",
		"wpbl%.dnsbl%.net%.au",
		"ws%.surbl%.org",
		"ybl%.megacity%.org",
		"zebl%.zoneedit%.com",
		"dnsbl%.mailshell%.net",
		"nospam%.login%-solutions%.ag",
		"nospam%.login%-solutions%.de",
		"hashserver%.cs%.trendmicro%.com",
		"g%.symantecliveupdate%.com",
		"dnsbl%.manitu%.net",
		"blackholes%.mail%-abuse%.org",
		"blacklist%.spambag%.org",
		"grid%-institut%.de",
		"newsmatic%.t%-online%.de",
		"uribl%.com",
		"blackholes%.intersil%.net",
		"blackholes%.wirehub%.net",
		"dnsbl%.delink%.net",
		"dnsbl%.dronebl%.org",
		"dnsbl%.freenet%.de",
		"apews%.org",
		"bl%.open%-whois%.org",
		"avqs%.mcafee%.com",
		-- DNS RBLs end
		"www%.dhd24%.comhttp",
		"Speedport_W_700V",
		"Speedport_W_500",
		"windnsup%.selfip%.org",
		"wpad",
		"WORKGROUP",
		"ARBEITSGRUPPE",
		"MSHEIMNETZ",
		"MSHOME",
	},
	-- we don't need to redirect ftp URIs for example
	["prefix-excludes"]={
		"tracker",
		"l33t",
		"msdos",
		"server\0320",
		"smtp",
		"pop",
		"pop3",
		"imap",
		"mail",
		"ldap",
		"_ldap",
		"isatap",
		"time",
		"ntp",
		"irc",
		"ftp",
		"nntp",
		"gw",
		"gate",
		"gateway",
		"ad",
		"ads",
		"img",
		"image",
		"pic",
		"picture",
		"crab2",
		"node02",
		"gwc1",
		"kisama",
		"gwcrab",
		"gwc",
		"overbeer",
		"_kerberos",
		"mailto",
		"proxy",
		"cache",
		"scp",
		"sip",
		"config",
		"update",
		"autodiscover",
		"autoproxy",
		"wwwproxy",
		"autocache",
		"www%-proxy",
		"mailto%-t%-online",
		"exchange",
		"wpad",
		"autoconfig",
		"rvservice",
		"rvmail",
	},
	-- things that people often punch in their browsers
	["full-matches"]={
		"admin",
		"analytics",
		"aol",
		"amazon",
		"dell",
		"desktop",
		"download",
		"facebook",
		"family",
		"finance",
		"flickr",
		"forum",
		"gay",
		"go2",
		"home",
		"ibm",
		"imdb",
		"info",
		"localhost",
		"msn",
		"myspace",
		"profile",
		"proxy",
		"sb",
		"test",
		"top",
		"users",
		"xyz",
		"youtube",
		-- Characters close to "www" on the keyboard
		"qqq",
		"eee",
		"sss",
		"ddd",
		"333",
	},
	-- what we want to be redirected
	["prefix-matches"]={
		"w",
		"ww",
		"www",
		"wwww",
		"wwwww",
		"web",
		"http",
		"html",
		"home",
		"report",
		"wiki",
		"search",
		"xn%-%-",	
	},
	["suffix-matches"]={
		"example%.com",
		"yourdomain%.tld",
	},
	["return"]={
		{qtype="1", content="127.0.0.1", ttl=600, place="1"},
	},
}

function preresolve ( ip, destination, domain, qtype )
	-- here we return our stats counters via DNS ;-)
	if domain == "nxr_stat_full_match." and qtype == pdns.TXT
	then
		stat="\"" .. nxr_stat_full_match .. "\""
		return 0, {{qtype="16", ttl=1, place="1", content=stat},}
	end
	if domain == "nxr_stat_full_match_dialin." and qtype == pdns.TXT
	then
		stat="\"" .. nxr_stat_full_match_dialin .. "\""
		return 0, {{qtype="16", ttl=1, place="1", content=stat},}
	end
	if domain == "nxr_stat_prefix_match." and qtype == pdns.TXT
	then
		stat="\"" .. nxr_stat_prefix_match .. "\""
		return 0, {{qtype="16", ttl=1, place="1", content=stat},}
	end
	if domain == "nxr_stat_prefix_match_dialin." and qtype == pdns.TXT
	then
		stat="\"" .. nxr_stat_prefix_match_dialin .. "\""
		return 0, {{qtype="16", ttl=1, place="1", content=stat},}
	end
	if domain == "nxr_stat_prefix_exclude." and qtype == pdns.TXT
	then
		stat="\"" .. nxr_stat_prefix_exclude .. "\""
		return 0, {{qtype="16", ttl=1, place="1", content=stat},}
	end
	if domain == "nxr_stat_prefix_exclude_dialin." and qtype == pdns.TXT
	then
		stat="\"" .. nxr_stat_prefix_exclude_dialin .. "\""
		return 0, {{qtype="16", ttl=1, place="1", content=stat},}
	end
	if domain == "nxr_stat_suffix_match." and qtype == pdns.TXT
	then
		stat="\"" .. nxr_stat_suffix_match .. "\""
		return 0, {{qtype="16", ttl=1, place="1", content=stat},}
	end
	if domain == "nxr_stat_suffix_match_dialin." and qtype == pdns.TXT
	then
		stat="\"" .. nxr_stat_suffix_match_dialin .. "\""
		return 0, {{qtype="16", ttl=1, place="1", content=stat},}
	end
	if domain == "nxr_stat_suffix_exclude." and qtype == pdns.TXT
	then
		stat="\"" .. nxr_stat_suffix_exclude .. "\""
		return 0, {{qtype="16", ttl=1, place="1", content=stat},}
	end
	if domain == "nxr_stat_suffix_exclude_dialin." and qtype == pdns.TXT
	then
		stat="\"" .. nxr_stat_suffix_exclude_dialin .. "\""
		return 0, {{qtype="16", ttl=1, place="1", content=stat},}
	end
	-- the fallthrough
	return -1, {}
end

function nxdomain ( ip, destination, domain, qtype )
	-- we only care about IN A or ANY queries here
	if qtype ~= 1 and qtype ~= 255
    then
            return -1, {}
    end
    if
            destination == "4.3.2.1"      -- we only redirect for the 4.3.2.1 DNS service IP
    then
		-- we do the whole enchilada only for networks in our nxrranges list
		if matchnetmask(ip, nxrranges)
		then
			-- we convert the query string to lower case so we can match it against our lowercase list
			domain=string.lower(domain)
			d=os.date("\"%Y%m%d%H%M%S\"")
			if string.find(domain, "^[%w%s-]+%.$")
			then
				nxr_stat_full_match=nxr_stat_full_match+1
				-- we count our dialin ranges extra
				if matchnetmask(ip, nxrranges_dialin)
				then
					nxr_stat_full_match_dialin=nxr_stat_full_match_dialin+1
				end
				-- as this is a full match we can return some A records instead of NXDOMAIN
				-- in this case this is even a round-robin-set
				return 0, {
					{qtype="1", content="127.0.0.1", ttl=3600, place="1"},
					{qtype="1", content="127.0.0.2", ttl=3600, place="1"},
				}
			end
			for i,v in pairs(nxr["suffix-excludes"])
			do
				if string.find(domain, v .. "%.$")
				then
					nxr_stat_suffix_exclude=nxr_stat_suffix_exclude+1
					if matchnetmask(ip, nxrranges_dialin)
					then
						nxr_stat_suffix_exclude_dialin=nxr_stat_suffix_exclude_dialin+1
					end
					return -1, {}
				end
			end
			for i,v in pairs(nxr["prefix-excludes"])
			do
				if string.find(domain, "^" .. v )
				then
					nxr_stat_prefix_exclude=nxr_stat_prefix_exclude+1
					if matchnetmask(ip, nxrranges_dialin)
					then
						nxr_stat_prefix_exclude_dialin=nxr_stat_prefix_exclude_dialin+1
					end
					return -1, {}
				end
			end
			for i,v in pairs(nxr["suffix-matches"])
			do
				if string.find(domain, "%." .. v .. "%.$")
				then
					nxr_stat_suffix_match=nxr_stat_suffix_match+1
					if matchnetmask(ip, nxrranges_dialin)
					then
						nxr_stat_suffix_match_dialin=nxr_stat_suffix_match_dialin+1
					end
					-- same as with the full match but here we matched something in the suffix list
					return 0, {
						{qtype="1", content="127.0.0.1", ttl=3600, place="1"},
						{qtype="1", content="127.0.0.2", ttl=3600, place="1"},
					}
				end
			end
			for i,v in pairs(nxr["prefix-matches"])
			do
				if string.find(domain, "^" .. v .. "%.")
				then
					nxr_stat_prefix_match=nxr_stat_prefix_match+1
					if matchnetmask(ip, nxrranges_dialin)
					then
						nxr_stat_prefix_match_dialin=nxr_stat_prefix_match_dialin+1
					end
					-- and this matched our prefix list
					return 0, {
						{qtype="1", content="127.0.0.1", ttl=3600, place="1"},
						{qtype="1", content="127.0.0.2", ttl=3600, place="1"},
					}
				end
			end
		end
	end
	-- again the fallthrough to the recursor, do _not_ let it out ;)
	return -1, {}
end