diff --git a/dist.ini b/dist.ini
index 4f53c7db48..d112f5b627 100644
--- a/dist.ini
+++ b/dist.ini
@@ -21,6 +21,8 @@ File::Temp = 0.22
URI::Escape = 3.31
; Forecast
Text::Trim = 0
+; IPLookup
+Regexp::IPv6 = 0
[GatherDir]
[PruneCruft]
diff --git a/lib/DDG/Spice/IPLookup.pm b/lib/DDG/Spice/IPLookup.pm
new file mode 100755
index 0000000000..dc5d2c717c
--- /dev/null
+++ b/lib/DDG/Spice/IPLookup.pm
@@ -0,0 +1,39 @@
+package DDG::Spice::IPLookup;
+# ABSTRACT: Returns information about an IP address
+
+use DDG::Spice;
+use Regexp::IPv6 qw($IPv6_re);
+
+primary_example_queries "reverse dns 8.8.8.8";
+description "Shows reverse DNS information about an IP";
+name "IPLookup";
+category 'computing_tools';
+topics "sysadmin";
+
+attribution github => ['https://github.com/mintsoft', 'mintsoft'],
+ web => 'http://www.robtex.com/';
+
+triggers startend => 'ip lookup', 'iplookup', 'reverse dns', 'reverse ip', 'dns', 'whois';
+
+spice to => 'https://www.robtex.com/ext/xapiq/?q=$1&filter=none&s=wip,asip,ddg&r=json';
+spice wrap_jsonp_callback => 1;
+
+sub is_ipv4($)
+{
+ my ($ip) = @_;
+ return undef unless $ip =~ /^([0-9]{1,3}\.){3}([0-9]{1,3})$/;
+ my @octlets = split /\./, $ip;
+ for (@octlets) {
+ return undef if int($_) > 255 || int($_) < 0;
+ }
+ return 1;
+}
+
+handle remainder => sub {
+ s/for|of|lookup//;
+ s/\s//;
+ return $_ if (is_ipv4($_) || /^$IPv6_re$/);
+ return;
+};
+
+1;
diff --git a/share/spice/iplookup/content.handlebars b/share/spice/iplookup/content.handlebars
new file mode 100755
index 0000000000..94ec583143
--- /dev/null
+++ b/share/spice/iplookup/content.handlebars
@@ -0,0 +1,16 @@
+
+ {{#each famlist from="0" to="1"}}
+
+ {{/each}}
+
Owner: {{shortwho}}
+
{{shortloc}}
+ {{#if blacklists}}
+
Blacklists:
+
+ {{#each blacklists}}
+ - {{this}}
+ {{/each}}
+
+
+ {{/if}}
+
\ No newline at end of file
diff --git a/share/spice/iplookup/iplookup.css b/share/spice/iplookup/iplookup.css
new file mode 100755
index 0000000000..19b57ecb8b
--- /dev/null
+++ b/share/spice/iplookup/iplookup.css
@@ -0,0 +1,34 @@
+ul.blacklists
+{
+ margin: 0;
+ padding: 0;
+ padding-top: 0.2em;
+}
+
+.zci h1.iplookup_domain_name
+{
+ font-size: 1.5em;
+ font-weight: 500;
+ margin-bottom: 0;
+}
+
+.iplookup_owner
+{
+ font-size: 1.3em;
+ font-weight: 300;
+}
+
+.zci__more-at--info img
+{
+ padding-right: 0.4em;
+}
+
+.iplookup_blacklist
+{
+ margin-top: 0.5em;
+}
+
+.iplookup_location, .iplookup_blacklist
+{
+ margin-bottom: 0.5em;
+}
\ No newline at end of file
diff --git a/share/spice/iplookup/iplookup.js b/share/spice/iplookup/iplookup.js
new file mode 100755
index 0000000000..ce66397a5f
--- /dev/null
+++ b/share/spice/iplookup/iplookup.js
@@ -0,0 +1,30 @@
+(function (env) {
+ "use strict";
+ env.ddg_spice_iplookup = function(api_result){
+
+ if (!api_result || api_result.error) {
+ return Spice.failed('iplookup');
+ }
+
+ Spice.add({
+ id: "iplookup",
+ name: "Answer",
+ data: api_result.ddg,
+ meta: {
+ sourceName: "RobTex",
+ sourceUrl: api_result.ddg.lnk
+ },
+ templates: {
+ group: 'info',
+ options: {
+ content: Spice.iplookup.content
+ }
+ },
+ relevancy: {
+ primary: [{
+ required: 'shortwho'
+ }]
+ }
+ });
+ };
+}(this));
diff --git a/t/IPLookup.t b/t/IPLookup.t
new file mode 100755
index 0000000000..7ef68bab96
--- /dev/null
+++ b/t/IPLookup.t
@@ -0,0 +1,72 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Test::More;
+use DDG::Test::Spice;
+
+ddg_spice_test(
+ [qw( DDG::Spice::IPLookup )],
+ 'reverse dns 8.8.8.8' => test_spice(
+ '/js/spice/iplookup/8.8.8.8',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup',
+ ),
+ 'reverse dns for 1.2.3.4' => test_spice(
+ '/js/spice/iplookup/1.2.3.4',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup',
+ ),
+ 'reverse dns of 1.2.3.4' => test_spice(
+ '/js/spice/iplookup/1.2.3.4',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup',
+ ),
+ 'reverse dns lookup 1.2.3.4' => test_spice(
+ '/js/spice/iplookup/1.2.3.4',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup',
+ ),
+ 'dns of 1.2.3.4' => test_spice(
+ '/js/spice/iplookup/1.2.3.4',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup',
+ ),
+ 'reverse ip lookup 1.2.3.4' => test_spice(
+ '/js/spice/iplookup/1.2.3.4',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup',
+ ),
+ 'dns 10.20.30.40' => test_spice(
+ '/js/spice/iplookup/10.20.30.40',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup',
+ ),
+ 'whois 1.2.3.4' => test_spice(
+ '/js/spice/iplookup/1.2.3.4',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup',
+ ),
+ 'reverse dns 256.8.8.8' => undef,
+ 'reverse dns a.b.c.d' => undef,
+ 'reverse dns duckduckgo.com' => undef,
+ 'reverse dns for a.b.c.d' => undef,
+ 'reverse dns for 2607:f0d0:1002:0051:0000:0000:0000:0004' => test_spice(
+ '/js/spice/iplookup/2607%3Af0d0%3A1002%3A0051%3A0000%3A0000%3A0000%3A0004',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup',
+ ),
+ 'ip lookup for 5.6.7.8' => test_spice(
+ '/js/spice/iplookup/5.6.7.8',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup'
+ ),
+ 'reverse dns for fe80::200:f8ff:fe21:67cf' => test_spice(
+ '/js/spice/iplookup/fe80%3A%3A200%3Af8ff%3Afe21%3A67cf',
+ call_type => 'include',
+ caller => 'DDG::Spice::IPLookup',
+ ),
+);
+
+done_testing;
+