diff --git a/pdns-server/bin/pdns-dnscap2feeder.sh b/pdns-server/bin/pdns-dnscap2feeder.sh
new file mode 100644
index 0000000..9fb6ddb
--- /dev/null
+++ b/pdns-server/bin/pdns-dnscap2feeder.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+#
+# A simple feeder using dnscap input
+#
+
+./dnscap -T -s r -ieth1 -g 2>&1 >/dev/null | perl pdns-feeder.pl
diff --git a/pdns-server/bin/pdns-feeder.pl b/pdns-server/bin/pdns-feeder.pl
new file mode 100644
index 0000000..b7b5b0d
--- /dev/null
+++ b/pdns-server/bin/pdns-feeder.pl
@@ -0,0 +1,147 @@
+#
+# Minimal and Scalable Passive DNS - Redis feeder
+#
+# Read dnscap output to feed a Redis database
+#
+#
+# Copyright (C) 2010-2012 Alexandre Dulaunoy
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+use strict;
+use warnings;
+
+use Date::Manip;
+use Redis;
+use Scalar::Util;
+use IO::Handle;
+
+$| = 1;
+
+my $block = 0;
+my $date;
+my %counter = (
+ "processed" => 0,
+ "redisrst" => 0
+);
+my @RRType = ( "A", "AAAA", "CNAME", "NS" );
+my %RRTypevalue = (
+ "A" => 1,
+ "AAAA" => 28,
+ "CNAME" => 5,
+ "NS" => 2,
+ "MX" => 15,
+ "SRV" => 33
+);
+
+my $parsedate = new Date::Manip::Date;
+
+my $r = Redis->new( server => '127.0.0.1:6379', encoding => undef );
+
+my $stdin = new IO::Handle;
+$stdin->fdopen( fileno(STDIN), "r" );
+
+while ( defined( $_ = $stdin->getline ) ) {
+
+ if ( $counter{'redisrst'} == 1 ) {
+ $r->quit;
+ undef($r);
+ print "Reset\n";
+ $r = Redis->new( server => '127.0.0.1:6379', encoding => undef );
+ $counter{'redisrst'} = 0;
+ }
+ if (m/^\[/) {
+ $block = 1;
+ {
+ my @s = split;
+ $date = $s[1];
+ }
+ }
+
+ if ( !(m/^\[/) ) {
+ $_ =~ s/\cI//;
+
+ # discarding - [1.2.3.4].53 [149.13.33.69].5234
+ if (m/^\[/) { next; }
+
+ # split - 21 ns10.ovh.net,IN,AAAA,172800,2001:41d0:1:1981::1 \
+ if (m/^\d* /) {
+ $_ =~ s/^\d* //;
+ }
+
+ # discarding - dns QUERY,NOERROR,26278,qr|rd|ra \
+ if (m/^dns /) { next; }
+
+ # decode line
+ ProcessRequest( $date, $_ );
+ $counter{'processed'}++;
+ }
+ if ( ( $counter{'processed'} % 1000 ) == 0 ) {
+ $counter{'redisrst'} = 1;
+ print "Processed:"
+ . $counter{'processed'}
+ . " Redist RST:"
+ . $counter{'redisrst'} . "\n";
+ }
+
+}
+
+sub ProcessRequest {
+ my $epoch = shift;
+ my $line = shift;
+ chomp($line);
+
+ #my $err = $parsedate->parse($date);
+ #my $epoch = $parsedate->printf('%s');
+
+ my @l = split( /,/, $line );
+ if ( $l[2] ~~ @RRType ) {
+ my @rdatas = split( / /, $l[4] );
+
+ #$l[4] =~ s/\s\\.*$//g;
+ #$l[4] =~ s/(.*)\s/$1/g;
+ print $l[0] . " " . $l[2] . " " . "$rdatas[0]\n";
+ my @rdatap = split( / /, $l[4] );
+ RedisUpdate( $l[0], $l[2], $rdatap[0], $epoch );
+ undef(@rdatap);
+ }
+}
+
+sub RedisUpdate {
+ my $name = lc(shift);
+ my $recordtype = shift;
+ my $rdata = lc(shift);
+ my $timestamp = shift;
+
+ my $recordtypevalue = $RRTypevalue{$recordtype};
+ my $pdns_r = "r:" . $name . ":" . $recordtypevalue;
+ my $pdns_v = "v:" . $rdata;
+ my $pdns_s = "s:" . $name . ":" . $rdata;
+ my $pdns_l = "l:" . $name . ":" . $rdata;
+ my $pdns_o = "o:" . $name . ":" . $rdata;
+
+ my $ret = $r->sadd( $pdns_r, $rdata );
+ $ret = $r->sadd( $pdns_v, $name );
+
+ # set first seen value
+ if ( !( $r->exists($pdns_s) ) ) {
+ $ret = $r->set( $pdns_s, $timestamp );
+ }
+
+ # set last seen value
+ $ret = $r->set( $pdns_l, $timestamp );
+
+ # increment the occurence value
+ $ret = $r->incr($pdns_o);
+}
diff --git a/pdns-server/bin/pdns-ranking.py b/pdns-server/bin/pdns-ranking.py
new file mode 100644
index 0000000..5cf13bd
--- /dev/null
+++ b/pdns-server/bin/pdns-ranking.py
@@ -0,0 +1,85 @@
+#
+# Minimal and Scalable Passive DNS - ranking records
+#
+# Copyright (C) 2012 Alexandre Dulaunoy
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+# Sample input (pdns-ranking.py) read line with the Passive DNS format:
+# s:truecsi.org:ns3.afraid.org. = 1327737190
+#
+# and output the following:
+# truecsi.org
+# [(1.0003765060241001, 'truecsi.org')]
+# truecsi.org,1.00037650602
+#
+# and update the DB 6 database
+# redis> select 6
+# OK
+# redis> KEYS "*"
+# 1) "truecsi.org"
+# redis> GET "truecsi.org"
+# "1.00037650602"
+# redis>
+
+
+import sys
+import re
+import redis
+
+path = "../lib/DomainClassifier/DomainClassifier/"
+sys.path.append(path)
+
+import domainclassifier
+
+
+def domexist(ldomain = None):
+ print ldomain
+ r = redis.StrictRedis(host='localhost', port=6379, db=6)
+
+ if ldomain is not None:
+ if r.exists(ldomain):
+ return True
+ else:
+ return False
+ else:
+ return False
+
+def domstore(ldomain = None, rank = 1.0):
+ r = redis.StrictRedis(host='localhost', port=6379, db=6)
+ return r.set(ldomain,rank)
+
+for line in sys.stdin:
+ domain = line.split(':')[1].lower()
+ if not (re.search("(spamhaus.org|arpa)$", domain)):
+ if not domexist(ldomain=domain):
+ c = domainclassifier.Extract(domain)
+ c.domain()
+ c.validdomain()
+ r = c.rankdomain()
+ if r:
+ r.sort(reverse=True)
+ ranking = r[0][0]
+ print r
+ if ranking is not None:
+ print domain+","+str(ranking)
+ domstore(ldomain=domain, rank=ranking)
+ else:
+ print domain+","+str(1)
+ domstore(ldomain=domain)
+ else:
+ print domain+","+str(1)
+ domstore(ldomain=domain)
+ else:
+ print domain+" already cached"
diff --git a/pdns-server/bin/query.pl b/pdns-server/bin/query.pl
new file mode 100644
index 0000000..661c49f
--- /dev/null
+++ b/pdns-server/bin/query.pl
@@ -0,0 +1,114 @@
+#
+# Minimal and Scalable Passive DNS - Query tool
+#
+# Copyright (C) 2010-2012 Alexandre Dulaunoy
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+
+use POSIX qw(strftime);
+use Redis;
+use Date::Manip;
+
+# will lookup the following RR types
+my %RRTypevalue = (
+ "A" => 1,
+ "AAAA" => 28,
+ "CNAME" => 5,
+ "NS" => 2
+
+);
+
+my $r = Redis->new( server => '127.0.0.1:6379', encoding => undef );
+
+#sample feeder input
+#1298823157.764221 "SET" "l:www.l.google.com:72.14.204.103" "1298819557"
+#1298823157.764353 "INCR" "o:www.l.google.com:72.14.204.103"
+#1298823157.765310 "SADD" "r:www.l.google.com:1" "72.14.204.104"
+#1298823157.765439 "SADD" "v:72.14.204.104" "www.l.google.com"
+#1298823157.765567 "EXISTS" "s:www.l.google.com:72.14.204.104"
+#1298823157.765696 "SET" "l:www.l.google.com:72.14.204.104" "1298819557"
+#1298823157.765823 "INCR" "o:www.l.google.com:72.14.204.104"
+#1298823157.766776 "SADD" "r:www.l.google.com:1" "72.14.204.147"
+#1298823157.766901 "SADD" "v:72.14.204.147" "www.l.google.com"
+#1298823157.767086 "EXISTS" "s:www.l.google.com:72.14.204.147"
+#1298823157.767207 "SET" "l:www.l.google.com:72.14.204.147" "1298819557"
+#1298823157.767333 "INCR" "o:www.l.google.com:72.14.204.147"
+
+while ( my ( $typename, $typevalue ) = each(%RRTypevalue) ) {
+
+ my @x = Lookup( $ARGV[0], $typevalue );
+
+ if ( defined(@x) ) {
+ foreach $p (@x) {
+ print $p. "("
+ . $typename . ")"
+ . " first seen: "
+ . NiceDate( FirstSeen( $ARGV[0], $p ) )
+ . " last seen: "
+ . NiceDate( LastSeen( $ARGV[0], $p ) )
+ . " Hits: "
+ . OccTuple( $ARGV[0], $p ) . "\n";
+ print " behind: " . join( ",", LookupIP($p) ) . "\n";
+ }
+ }
+
+}
+
+sub NiceDate {
+ my $epochvalue = shift;
+
+ return strftime( "%Y%m%d-%H:%M:%S", localtime($epochvalue) );
+
+}
+
+sub Lookup {
+ my $name = shift;
+ my $type = shift;
+
+ # default A record
+ if ( !( defined($type) ) ) { $type = 1; }
+ my $key = "r:$name:$type";
+ return $r->smembers($key);
+}
+
+sub LookupIP {
+ my $name = shift;
+ my $key = "v:$name";
+ return $r->smembers($key);
+}
+
+sub FirstSeen {
+ my $name = shift;
+ my $rdata = shift;
+
+ my $key = "s:$name:$rdata";
+ return $r->get($key);
+}
+
+sub LastSeen {
+ my $name = shift;
+ my $rdata = shift;
+
+ my $key = "l:$name:$rdata";
+ return $r->get($key);
+}
+
+sub OccTuple {
+ my $name = shift;
+ my $rdata = shift;
+
+ my $key = "o:$name:$rdata";
+ return $r->get($key);
+}
diff --git a/pdns-server/doc/RR-Type.txt b/pdns-server/doc/RR-Type.txt
new file mode 100644
index 0000000..f04600a
--- /dev/null
+++ b/pdns-server/doc/RR-Type.txt
@@ -0,0 +1,79 @@
+A 1 a host address [RFC1035]
+NS 2 an authoritative name server [RFC1035]
+MD 3 a mail destination (Obsolete - use MX) [RFC1035]
+MF 4 a mail forwarder (Obsolete - use MX) [RFC1035]
+CNAME 5 the canonical name for an alias [RFC1035]
+SOA 6 marks the start of a zone of authority [RFC1035]
+MB 7 a mailbox domain name (EXPERIMENTAL) [RFC1035]
+MG 8 a mail group member (EXPERIMENTAL) [RFC1035]
+MR 9 a mail rename domain name (EXPERIMENTAL) [RFC1035]
+NULL 10 a null RR (EXPERIMENTAL) [RFC1035]
+WKS 11 a well known service description [RFC1035]
+PTR 12 a domain name pointer [RFC1035]
+HINFO 13 host information [RFC1035]
+MINFO 14 mailbox or mail list information [RFC1035]
+MX 15 mail exchange [RFC1035]
+TXT 16 text strings [RFC1035]
+RP 17 for Responsible Person [RFC1183]
+AFSDB 18 for AFS Data Base location [RFC1183][RFC5864]
+X25 19 for X.25 PSDN address [RFC1183]
+ISDN 20 for ISDN address [RFC1183]
+RT 21 for Route Through [RFC1183]
+NSAP 22 for NSAP address, NSAP style A record [RFC1706]
+NSAP-PTR 23 for domain name pointer, NSAP style [RFC1348]
+SIG 24 for security signature [RFC4034][RFC3755][RFC2535]
+KEY 25 for security key [RFC4034][RFC3755][RFC2535]
+PX 26 X.400 mail mapping information [RFC2163]
+GPOS 27 Geographical Position [RFC1712]
+AAAA 28 IP6 Address [RFC3596]
+LOC 29 Location Information [RFC1876]
+NXT 30 Next Domain - OBSOLETE [RFC3755][RFC2535]
+EID 31 Endpoint Identifier [Patton]
+NIMLOC 32 Nimrod Locator [Patton]
+SRV 33 Server Selection [RFC2782]
+ATMA 34 ATM Address [ATMDOC]
+NAPTR 35 Naming Authority Pointer [RFC2915][RFC2168][RFC3403]
+KX 36 Key Exchanger [RFC2230]
+CERT 37 CERT [RFC4398]
+A6 38 A6 (Experimental) [RFC3226][RFC2874]
+DNAME 39 DNAME [RFC2672]
+SINK 40 SINK [Eastlake]
+OPT 41 OPT [RFC2671]
+APL 42 APL [RFC3123]
+DS 43 Delegation Signer [RFC4034][RFC3658]
+SSHFP 44 SSH Key Fingerprint [RFC4255]
+IPSECKEY 45 IPSECKEY [RFC4025]
+RRSIG 46 RRSIG [RFC4034][RFC3755]
+NSEC 47 NSEC [RFC4034][RFC3755]
+DNSKEY 48 DNSKEY [RFC4034][RFC3755]
+DHCID 49 DHCID [RFC4701]
+NSEC3 50 NSEC3 [RFC5155]
+NSEC3PARAM 51 NSEC3PARAM [RFC5155]
+Unassigned 52-54
+HIP 55 Host Identity Protocol [RFC5205]
+NINFO 56 NINFO [Reid]
+RKEY 57 RKEY [Reid]
+TALINK 58 Trust Anchor LINK [Wijngaards]
+Unassigned 59-98
+SPF 99 [RFC4408]
+UINFO 100 [IANA-Reserved]
+UID 101 [IANA-Reserved]
+GID 102 [IANA-Reserved]
+UNSPEC 103 [IANA-Reserved]
+Unassigned 104-248
+TKEY 249 Transaction Key [RFC2930]
+TSIG 250 Transaction Signature [RFC2845]
+IXFR 251 incremental transfer [RFC1995]
+AXFR 252 transfer of an entire zone [RFC1035][RFC5936]
+MAILB 253 mailbox-related RRs (MB, MG or MR) [RFC1035]
+MAILA 254 mail agent RRs (Obsolete - see MX) [RFC1035]
+* 255 A request for all records [RFC1035]
+URI 256 URI [Faltstrom]
+Unassigned 257-32767
+TA 32768 DNSSEC Trust Authorities [Weiler] 2005-12-13
+DLV 32769 DNSSEC Lookaside Validation [RFC4431]
+Unassigned 32770-65279
+Private use 65280-65534
+Reserved 65535
+
+
diff --git a/pdns-server/doc/datastore-format.txt b/pdns-server/doc/datastore-format.txt
new file mode 100644
index 0000000..98d1f54
--- /dev/null
+++ b/pdns-server/doc/datastore-format.txt
@@ -0,0 +1,97 @@
+This is a description of the various data-structure used
+in the Passive DNS toolkit.
+
+= Redis Database number =
+
+ - (0) default passive dns
+ - (6) ranking of hostname
+
+= format for redis db 0 =
+
+KEY, VALUE
+
+s:
+l:
+o:
+
+KEY, {SET}
+
+r:: {}
+v: {}
+
+# "SET" "l:www.l.google.com:72.14.204.103" "1298819557"
+#1298823157.764353 "INCR" "o:www.l.google.com:72.14.204.103"
+#1298823157.765310 "SADD" "r:www.l.google.com:1" "72.14.204.104"
+#1298823157.765439 "SADD" "v:72.14.204.104" "www.l.google.com"
+#1298823157.765567 "EXISTS" "s:www.l.google.com:72.14.204.104"
+#1298823157.765696 "SET" "l:www.l.google.com:72.14.204.104" "1298819557"
+#1298823157.765823 "INCR" "o:www.l.google.com:72.14.204.104"
+#1298823157.766776 "SADD" "r:www.l.google.com:1" "72.14.204.147"
+#1298823157.766901 "SADD" "v:72.14.204.147" "www.l.google.com"
+#1298823157.767086 "EXISTS" "s:www.l.google.com:72.14.204.147"
+#1298823157.767207 "SET" "l:www.l.google.com:72.14.204.147" "1298819557"
+#1298823157.767333 "INCR" "o:www.l.google.com:72.14.204.147"
+
+
+== sample db 0 ==
+
+Here is the classical update process for a feeder:
+
+Set or update the last-seen.
+
+#1298823157.764221 "SET" "l:www.l.google.com:72.14.204.103" "1298819557"
+
+Update the occurence of the answer seen.
+
+#1298823157.764353 "INCR" "o:www.l.google.com:72.14.204.103"
+
+Add to a set "record:rr-type" the seen answer.
+
+#1298823157.765310 "SADD" "r:www.l.google.com:1" "72.14.204.104"
+
+Add the reverse for fast lookup.
+
+#1298823157.765439 "SADD" "v:72.14.204.104" "www.l.google.com"
+
+If there is no existing first-seen for the tuple,
+
+#1298823157.765567 "EXISTS" "s:www.l.google.com:72.14.204.104"
+
+A first-seen is set:
+
+#1298823157.765696 "SET" "l:www.l.google.com:72.14.204.104" "1298819557"
+
+and so on...
+
+#1298823157.765823 "INCR" "o:www.l.google.com:72.14.204.104"
+#1298823157.766776 "SADD" "r:www.l.google.com:1" "72.14.204.147"
+#1298823157.766901 "SADD" "v:72.14.204.147" "www.l.google.com"
+#1298823157.767086 "EXISTS" "s:www.l.google.com:72.14.204.147"
+#1298823157.767207 "SET" "l:www.l.google.com:72.14.204.147" "1298819557"
+#1298823157.767333 "INCR" "o:www.l.google.com:72.14.204.147"
+
+= format for redis db 6 =
+
+This db index hold a ranking value per hostname.
+
+KEY, VALUE
+
+hostname, float double precision
+
+This can be seen as a cache when an expiration can be set
+by key to limit the lifetime of a ranking. You can create
+a persistent ranking for setting up some "golden" domains.
+
+== sample db 6 ==
+
+1) "truecsi.org"
+redis> GET "truecsi.org"
+"1.00037650602"
+redis>
+
+= contact =
+
+Update, extension, or new data-structure more than welcome.
+
+https://www.github.com/adulau/
+
diff --git a/pdns-server/lib/install.sh b/pdns-server/lib/install.sh
new file mode 100644
index 0000000..e0829da
--- /dev/null
+++ b/pdns-server/lib/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+git clone git://github.com/adulau/DomainClassifier.git
diff --git a/pdns-server/web/PDNSq.pm b/pdns-server/web/PDNSq.pm
new file mode 100644
index 0000000..9aad7ba
--- /dev/null
+++ b/pdns-server/web/PDNSq.pm
@@ -0,0 +1,171 @@
+#
+# Minimal and Scalable Passive DNS - Query tool
+#
+# Copyright (C) 2010-2012 Alexandre Dulaunoy
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+package PDNS::Query;
+
+use base 'Exporter';
+
+use POSIX qw(strftime);
+use Redis;
+use Date::Manip;
+use Time::Format;
+
+my %RRTypevalue = (
+ "A" => 1,
+ "NS" => 2,
+ "AAAA" => 28,
+ "CNAME" => 5
+);
+
+my $r = Redis->new( server => '127.0.0.1:6379', encoding => undef );
+
+my $burl = "/l/";
+
+sub Query {
+
+ my $query = shift;
+ my $ret = "";
+ $ret .= "[+-]";
+ $ret .= "
";
+ return $ret;
+}
+
+sub QueryJSON {
+ my $query = shift;
+ my $ret = <$value ";
+ return $ret;
+}
+
+sub NiceDate {
+ my $epochvalue = shift;
+
+ return strftime( "%Y%m%d-%H:%M:%S", localtime($epochvalue) );
+
+}
+
+sub NiceDateISO {
+ my $epochvalue = shift;
+ my $format = "yyyy-mm{on}-ddThh:mm:ss+00:00";
+ return time_format( $format, $epochvalue );
+}
+
+sub Lookup {
+ my $name = shift;
+ my $type = shift;
+
+ # default A record
+ if ( !( defined($type) ) ) { $type = 1; }
+ my $key = "r:$name:$type";
+ return $r->smembers($key);
+}
+
+sub LookupIP {
+ my $name = shift;
+ my $key = "v:$name";
+ return $r->smembers($key);
+}
+
+sub FirstSeen {
+ my $name = shift;
+ my $rdata = shift;
+
+ my $key = "s:$name:$rdata";
+ return $r->get($key);
+}
+
+sub LastSeen {
+ my $name = shift;
+ my $rdata = shift;
+
+ my $key = "l:$name:$rdata";
+ return $r->get($key);
+}
+
+sub OccTuple {
+ my $name = shift;
+ my $rdata = shift;
+
+ my $key = "o:$name:$rdata";
+ return -1;
+
+ #return $r->get($key);
+}
+
+1;
diff --git a/pdns-server/web/pdns-web.pl b/pdns-server/web/pdns-web.pl
new file mode 100755
index 0000000..bb09711
--- /dev/null
+++ b/pdns-server/web/pdns-web.pl
@@ -0,0 +1,214 @@
+#!/bin/env perl
+#
+# Minimal and Scalable Passive DNS - Web interface
+#
+# Copyright (C) 2010-2012 Alexandre Dulaunoy
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+
+use Mojolicious::Lite;
+use Mojolicious::Static;
+use PDNSq;
+
+# Documentation browser under "/perldoc" (this plugin requires Perl 5.10)
+plugin 'pod_renderer';
+
+get '/l/(.query)' => sub {
+ my $self = shift;
+ my $q = $self->param('query');
+ my $ret = PDNS::Query::Query($q);
+ my $json = PDNS::Query::QueryJSON($q);
+ $self->render(template => 'index', q => $ret, query => $q, jq => $json);
+};
+
+post '/l' => sub {
+ my $self = shift;
+ my $q = $self->param('q');
+ my $ret = PDNS::Query::Query($q);
+ my $json = PDNS::Query::QueryJSON($q);
+ $self->render(template => 'index', q => $ret, query => $q, jq => $json);
+};
+
+get '/js/(.query)' => sub {
+ my $self = shift;
+ my $q = $self->param('query');
+ $self->render_static('static/'.$q);
+};
+
+get '/__history__.html' => sub {
+ my $self = shift;
+ $self->render_static('static/__history__.html');
+};
+
+get '/' => sub {
+ my $self = shift;
+ $self->render(template => 'main');
+};
+
+
+app->secret('You have to change it');
+app->start;
+__DATA__
+
+@@ main.html.ep
+% layout 'default';
+% title 'Passive DNS';
+