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"}} +

{{this}}

+ {{/each}} +
Owner: {{shortwho}}
+
{{shortloc}}
+ {{#if blacklists}} +
Blacklists: + +
+ {{/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; +