#!/usr/local/bin/perl

# SORBS DNS Server v.2b
# 
# the folks at SORBS (http://www.sorbs.net/) can take a break..
# this program forecasts all SORBS actions and is much more
# comprehensive than an organization can ever be.  
# Guaranteed to block 100% of your spam.

# due to amazing response, please note this program is for
# entertainment purposes only.

use strict;
use Net::DNS::Nameserver; # blocking

my $ns = Net::DNS::Nameserver->new(
     LocalAddr    => '127.0.0.1',
     LocalPort    => 53,
     ReplyHandler => \&reply_handler,
     Verbose      => 0,
 ) || die "couldn't create nameserver object\n";
 
$ns->main_loop;

sub reply_handler {
	my ($qname, $qclass, $qtype, $peerhost) = @_;
	my ($rcode, @ans, @auth, @add);

	if($qname =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.([a-z]{3,7}\.)?(rh|dn)sbl\.sorbs\.net\.?$/){
		my ($a,$b,$c,$d) = ($4,$3,$2,$1);
		$rcode = 'NOERROR';
		if($qtype eq 'A' || $qtype eq 'ANY' || $qtype eq 'TXT'){
			my $ttl = 172800;
			if($qtype eq 'A' || $qtype eq 'ANY'){
				my @a = (2..12);
				my $r = $a[rand(@a)];
				my $rdata = "127.0.0.$r";
				push @ans, Net::DNS::RR->new("$qname $ttl IN A $rdata");
			}
			if($qtype eq 'TXT' || $qtype eq 'ANY'){
				my $ip = "$a.$b.$c.$d";
				push @ans, Net::DNS::RR->new("$qname $ttl IN TXT \"See: http://www.dnsbl.sorbs.net/cgi-bin/lookip?IP=$ip\"");
			}
			my @servers = qw/rbl1.oregonstate.edu rbl2.oregonstate.edu sorbs.bl.xs4all.nl sorbs-sql1.vix.com rbldns0.sorbs.net rbldns2.sorbs.net rbldns3.sorbs.net/;
			my $num = @servers;
			while($num > 0){
				my $element = rand(@servers);
				$element =~ s/\..*//;
				my $server = $servers[$element];
				splice @servers, $element, 1;
				push @auth, Net::DNS::RR->new("dnsbl.sorbs.net $ttl IN NS $server");
				$num--;
			}
			push @add, Net::DNS::RR->new("sorbs.net $ttl IN TXT http://www.google.com/search?q=Worthless+Project");
		}else{
			push @auth, Net::DNS::RR->new("dnsbl.sorbs.net. 86400 IN SOA rbldns0.sorbs.net dns.isux.com. $^T 120 120 604800 3600");
		}
	 }else{
		$rcode = 'NXDOMAIN';
	 }
 
	return ($rcode, \@ans, \@auth, \@add, { aa => 1 });
}
