]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - data/rbot/plugins/iplookup.rb
ircbot: do not use debug in sendmsg() because it breaks script. script plugin: handle...
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / iplookup.rb
index a3f8f952658723eb2c7ea7a9ef379b48d9c45daa..715595e25ee07686fac757281f69002967b4c197 100644 (file)
-#################################################################\r
-# IP Lookup Plugin\r
-# ----------------------------\r
-# by Chris Gahan (chris@ill-logic.com)\r
-#\r
-# Purpose:\r
-# ------------------\r
-# Lets you lookup the owner and their address for any IP address\r
-# or IRC user.\r
-#\r
-#################################################################\r
-\r
-require 'socket'\r
-require 'resolv'\r
-\r
-#################################################################\r
-## ARIN Whois module...\r
-##\r
-\r
-module ArinWhois\r
-\r
-  class Chunk < Hash\r
-    def customer?\r
-      keys.grep(/^(City|Address|StateProv|(Org|Cust)Name)$/).any?\r
-    end\r
-    \r
-    def network?\r
-      keys.grep(/^(CIDR|NetHandle|Parent)$/).any?\r
-    end\r
-\r
-    def contact?\r
-      keys.grep(/^(R|Org)(Tech|Abuse)(Handle|Name|Phone|Email)$/).any?\r
-    end\r
-    \r
-    def valid?\r
-      customer? or network? or contact?\r
-    end\r
-    \r
-    def owner\r
-      self[keys.grep(/^(Org|Cust)Name$/).first]\r
-    end\r
-    \r
-    def location\r
-      "#{self['City']}, #{self['StateProv']}, #{self['Country']}"\r
-    end\r
-    \r
-    def address\r
-      "#{self['Address']}, #{location}  #{self['PostalCode']}"\r
-    end\r
-    \r
-  end\r
-\r
-  class ArinWhoisParser\r
-    \r
-    def initialize(data)\r
-      @data = data\r
-    end\r
-    \r
-    def split_array_at(a, &block)\r
-      return a unless a.any?\r
-      a = a.to_a\r
-      \r
-      results = []\r
-      last_cutpoint = 0\r
-      \r
-      a.each_with_index do |el,i|\r
-        if block.call(el)\r
-          unless i == 0\r
-            results << a[last_cutpoint...i]\r
-            last_cutpoint = i\r
-          end\r
-        end\r
-      end\r
-      \r
-      if last_cutpoint < a.size or last_cutpoint == 0\r
-        results << a[last_cutpoint..-1]\r
-      end\r
-      \r
-      results\r
-    end\r
-    \r
-    # Whois output format\r
-    # ------------------------\r
-    # Owner info block:\r
-    #   {Org,Cust}Name\r
-    #   Address\r
-    #   City\r
-    #   StateProv\r
-    #   PostalCode\r
-    #   Country (2-digit)\r
-    #\r
-    # Network Information:\r
-    #   CIDR (69.195.25.0/25)\r
-    #   NetHandle (NET-72-14-192-0-1)\r
-    #   Parent (NET-72-0-0-0-0)\r
-    #\r
-    # Contacts:\r
-    #   ({R,Org}{Tech,Abuse}{Handle,Name,Phone,Email})*\r
-    \r
-    def parse_chunks\r
-      return if @data =~ /^No match found /\r
-      chunks = @data.gsub(/^# ARIN WHOIS database, last updated.+/m, '').scan(/(([^\n]+\n)+\n)/m)\r
-      chunks.map do |chunk|\r
-        result = Chunk.new\r
-        \r
-        chunk[0].scan(/([A-Za-z]+?):(.*)/).each do |tuple|\r
-          #puts tuple.inspect\r
-          result[tuple[0]] = tuple[1].strip\r
-        end\r
-        \r
-        result\r
-      end\r
-    end\r
-    \r
-    \r
-    def get_parsed_data\r
-      return unless chunks = parse_chunks\r
-      \r
-      results = split_array_at(parse_chunks) {|chunk|chunk.customer?}\r
-      results.map do |chunks|\r
-        {\r
-          :customer => chunks.select{|x|x.customer?}[0],\r
-          :net      => chunks.select{|x|x.network?}[0],\r
-          :contacts => chunks.select{|x|x.contact?}\r
-        }\r
-      end\r
-    end\r
-    \r
-    # Return a hash with :customer, :net, and :contacts info filled in.\r
-    def get_most_specific_owner\r
-      return unless datas = get_parsed_data\r
-      \r
-      datas_with_bitmasks = datas.map do |data| \r
-        bitmask = data[:net]['CIDR'].split('/')[1].to_i\r
-        [bitmask, data]\r
-      end\r
-      #datas_with_bitmasks.sort.each{|x|puts x[0]}\r
-      winner = datas_with_bitmasks.sort[-1][1]\r
-    end\r
-\r
-  end # of class ArinWhoisParser\r
-\r
-module_function\r
-\r
-  def raw_whois(query_string, host)\r
-    s = TCPsocket.open(host, 43)\r
-    s.write(query_string+"\n")\r
-    ret = s.read\r
-    s.close\r
-    return ret\r
-  end\r
-\r
-  def lookup(ip)\r
-    data = raw_whois("+#{ip}", 'whois.arin.net')\r
-    arin = ArinWhoisParser.new data\r
-    arin.get_most_specific_owner\r
-  end\r
-  \r
-  def lookup_location(ip)\r
-    result = lookup(ip)\r
-    result[:customer].location\r
-  end\r
-  \r
-  def lookup_address(ip)\r
-    result = lookup(ip)\r
-    result[:customer].address\r
-  end\r
-\r
-  def lookup_info(ip)\r
-    if result = lookup(ip)\r
-      "#{result[:net]['CIDR']} => #{result[:customer].owner} (#{result[:customer].address})"\r
-    else\r
-      "Address not found."\r
-    end\r
-  end\r
-\r
-end\r
-\r
-\r
-\r
-#################################################################\r
-## The Plugin\r
-##\r
-\r
-class IPLookupPlugin < Plugin\r
+#################################################################
+# IP Lookup Plugin
+# ----------------------------
+# by Chris Gahan (chris@ill-logic.com)
+#
+# Purpose:
+# ------------------
+# Lets you lookup the owner and their address for any IP address
+# or IRC user.
+#
+#################################################################
+
+require 'socket'
+require 'resolv'
+
+#################################################################
+## ARIN Whois module...
+##
+
+module ArinWhois
+
+  class Chunk < Hash
+    def customer?
+      keys.grep(/^(City|Address|StateProv|(Org|Cust)Name)$/).any?
+    end
+
+    def network?
+      keys.grep(/^(CIDR|NetHandle|Parent)$/).any?
+    end
+
+    def contact?
+      keys.grep(/^(R|Org)(Tech|Abuse)(Handle|Name|Phone|Email)$/).any?
+    end
+
+    def valid?
+      customer? or network? or contact?
+    end
+
+    def owner
+      self[keys.grep(/^(Org|Cust)Name$/).first]
+    end
+
+    def location
+      [ self['City'], self['StateProv'], self['Country'] ].compact.join(', ')
+    end
+
+    def address
+      [ self['Address'], location, self['PostalCode'] ].compact.join(', ')
+    end
+
+  end
+
+  class ArinWhoisParser
+
+    def initialize(data)
+      @data = data
+    end
+
+    def split_array_at(a, &block)
+      return a unless a.any?
+      a = a.to_a
+
+      results = []
+      last_cutpoint = 0
+
+      a.each_with_index do |el,i|
+        if block.call(el)
+          unless i == 0
+            results << a[last_cutpoint...i]
+            last_cutpoint = i
+          end
+        end
+      end
+
+      if last_cutpoint < a.size or last_cutpoint == 0
+        results << a[last_cutpoint..-1]
+      end
+
+      results
+    end
+
+    # Whois output format
+    # ------------------------
+    # Owner info block:
+    #   {Org,Cust}Name
+    #   Address
+    #   City
+    #   StateProv
+    #   PostalCode
+    #   Country (2-digit)
+    #
+    # Network Information:
+    #   CIDR (69.195.25.0/25)
+    #   NetHandle (NET-72-14-192-0-1)
+    #   Parent (NET-72-0-0-0-0)
+    #
+    # Contacts:
+    #   ({R,Org}{Tech,Abuse}{Handle,Name,Phone,Email})*
+
+    def parse_chunks
+      return if @data =~ /^No match found /
+      chunks = @data.gsub(/^# ARIN WHOIS database, last updated.+/m, '').scan(/(([^\n]+\n)+\n)/m)
+      chunks.map do |chunk|
+        result = Chunk.new
+
+        chunk[0].scan(/([A-Za-z]+?):(.*)/).each do |tuple|
+          tuple[1].strip!
+          result[tuple[0]] = tuple[1].empty? ? nil : tuple[1]
+        end
+
+        result
+      end
+    end
+
+
+    def get_parsed_data
+      return unless chunks = parse_chunks
+
+      results = split_array_at(parse_chunks) {|chunk|chunk.customer?}
+      results.map do |chunks|
+        {
+          :customer => chunks.select{|x|x.customer?}[0],
+          :net      => chunks.select{|x|x.network?}[0],
+          :contacts => chunks.select{|x|x.contact?}
+        }
+      end
+    end
+
+    # Return a hash with :customer, :net, and :contacts info filled in.
+    def get_most_specific_owner
+      return unless datas = get_parsed_data
+
+      datas_with_bitmasks = datas.map do |data|
+        bitmask = data[:net]['CIDR'].split('/')[1].to_i
+        [bitmask, data]
+      end
+      #datas_with_bitmasks.sort.each{|x|puts x[0]}
+      winner = datas_with_bitmasks.sort[-1][1]
+    end
+
+  end # of class ArinWhoisParser
+
+module_function
+
+  def raw_whois(query_string, host)
+    s = TCPsocket.open(host, 43)
+    s.write(query_string+"\n")
+    ret = s.read
+    s.close
+    return ret
+  end
+
+  def lookup(ip)
+    data = raw_whois("+#{ip}", 'whois.arin.net')
+    arin = ArinWhoisParser.new data
+    arin.get_most_specific_owner
+  end
+
+  def lookup_location(ip)
+    result = lookup(ip)
+    result[:customer].location
+  end
+
+  def lookup_address(ip)
+    result = lookup(ip)
+    result[:customer].address
+  end
+
+  def lookup_info(ip)
+    if result = lookup(ip)
+      "#{result[:net]['CIDR']} => #{result[:customer].owner} (#{result[:customer].address})"
+    else
+      "Address not found."
+    end
+  end
+
+end
+
+
+
+#################################################################
+## The Plugin
+##
+
+class IPLookupPlugin < Plugin
   def help(plugin, topic="")
     "iplookup [ip address / domain name] => lookup info about the owner of the IP address from the ARIN whois database"
-  end\r
-  \r
-  def iplookup(m, params)\r
-    reply = ""\r
-    if params[:domain]\r
-      ip = Resolv.getaddress(params[:domain])\r
-      reply += "(#{params[:domain]} = #{ip}) "\r
-    else\r
-      ip = params[:ip]\r
-    end\r
-    \r
-    reply += ArinWhois.lookup_info(ip)\r
-    m.reply reply\r
-  end\r
-\r
-  def userip(m, params)\r
-    #users = @channels[m.channel].users\r
-    #m.reply "users = #{users.inspect}"\r
-    #m.reply @bot.sendq("WHO #{params[:user]}")\r
-  end\r
-  \r
-end\r
-\r
+  end
+
+  def iplookup(m, params)
+    reply = ""
+    if params[:domain]
+      begin
+        ip = Resolv.getaddress(params[:domain])
+        reply += "#{params[:domain]} | "
+      rescue => e
+        m.reply "#{e.message}"
+        return
+      end
+    else
+      ip = params[:ip]
+    end
+
+    reply += ArinWhois.lookup_info(ip)
+    m.reply reply
+  end
+
+  def userip(m, params)
+    #users = @channels[m.channel].users
+    #m.reply "users = #{users.inspect}"
+    #m.reply @bot.sendq("WHO #{params[:user]}")
+  end
+
+end
+
 plugin = IPLookupPlugin.new
-plugin.map 'iplookup :ip', :action => 'iplookup', :requirements => {:ip => /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/}\r
-plugin.map 'iplookup :domain', :action => 'iplookup', :requirements => {:domain => /^[a-z0-9\.\-]{4,255}$/i}\r
+plugin.map 'iplookup :ip', :action => 'iplookup', :requirements => {:ip => /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/}
+plugin.map 'iplookup :domain', :action => 'iplookup', :requirements => {:domain => /^[a-z0-9\.\-]{4,255}$/i}
 plugin.map 'userip :user', :action => 'userip', :requirements => {:user => /\w+/}
-\r
-\r
-if __FILE__ == $0\r
-  include ArinWhois\r
-  data = open('whoiscgm.txt').read\r
-  c = ArinWhoisParser.new data\r
-  puts c.get_parsed_data.inspect\r
-end
\ No newline at end of file
+
+
+if __FILE__ == $0
+  include ArinWhois
+  data = open('whoistest.txt').read
+  c = ArinWhoisParser.new data
+  puts c.get_parsed_data.inspect
+end