module NicInfo

Copyright © 2011,2012,2013,2014 American Registry for Internet Numbers

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

IPv4 and IPv6 regular expressions are credited to Mike Poulson and are found here:

http://blogs.msdn.com/b/mpoulson/archive/2005/01/10/350037.aspx

Code based on “Enumerations and Ruby”

http://www.rubyfleebie.com/enumerations-and-ruby/

Copyright © 2017 American Registry for Internet Numbers

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Constants

ASN_BOOTSTRAP
ASN_REGEX
AS_REGEX
AS_ROOT_URL
AUTO_WRAP
BOOTSTRAP
BOOTSTRAP_FILE_DIR
BOOTSTRAP_URL
BSFILES_AGE
BSFILE_LAST_CHECK_FILENAME
CACHE
CACHE_EVICTION
CACHE_EXPIRY
CHECK_BSFILES_AGE
CLEAN_CACHE
COLOR_SCHEME
CONFIG
CONFIG_VERSION
DATA
DATA_FILE
DATA_TREE_ADDR_REGEX
DEFAULT_WIDTH
DEMO_DIR
DETECT_WIDTH
DNSSEC_ALGORITHMS
DNS_BOOTSTRAP
DOMAIN_REGEX
DOMAIN_ROOT_URL
DOMAIN_SRCH_REGEX
ENTITY_BOOTSTRAP
ENTITY_REGEX
ENTITY_ROOT_URL
EXTENDED_HELP
HELP_ROOT_URL
IP4_ARPA
IP6_ARPA
IPV4_BOOTSTRAP
IPV4_REGEX

IPv4 and IPv6 regular expressions are credited to Mike Poulson and are found here:

http://blogs.msdn.com/b/mpoulson/archive/2005/01/10/350037.aspx
IPV6_BOOTSTRAP
IPV6_HEXCOMPRESS_REGEX
IPV6_REGEX
IP_ROOT_URL
JCR_DIR

JCR Constants

JCR_ROOT_AUTNUM
JCR_ROOT_DOMAIN
JCR_ROOT_ENTITY
JCR_ROOT_ERROR
JCR_ROOT_HELP
JCR_ROOT_NAMESERVER
JCR_ROOT_NETWORK
JSON_CONTENT_TYPE
LASTTREE_YAML

File Name Constants

MESSAGES
MESSAGES_FILE
NET6_HANDLE_REGEX
NET_HANDLE_REGEX

regular expressions

NICINFO_DEMO_ERROR
NICINFO_DEMO_HINT
NICINFO_DEMO_URL

NicInfo values

NS_REGEX
OUTPUT

Config constants

PAGER
RDAP_CONTENT_TYPE

Other constants

RDAP_JCR
SECURITY
STRICT_RDAP_JCR
SUBSTRING
TRY_INSECURE
UPDATE_BSFILES
URL_REGEX
USE_CACHE
VERSION
VERSION_CONFIG
VERSION_LABEL

Public Class Methods

add_entity_nodes(entities, node) click to toggle source
# File lib/nicinfo/common_json.rb, line 44
def NicInfo.add_entity_nodes entities, node
  entities.each do |entity|
    entity_node = entity.to_node
    node.add_child( entity_node )
    NicInfo::add_entity_nodes( entity.entities, entity_node )
  end if entities
end
add_entity_respobjs(entities, respobjs) click to toggle source
# File lib/nicinfo/common_json.rb, line 52
def NicInfo.add_entity_respobjs entities, respobjs
  entities.each do |entity|
    respobjs.add( entity )
    NicInfo::add_entity_respobjs( entity.entities, respobjs )
  end if entities
end
capitalize(str) click to toggle source
# File lib/nicinfo/utils.rb, line 188
def NicInfo.capitalize str
  words = str.split( /\s/ )
  words.each do |word|
    word.capitalize!
  end
  return words.join( " " )
end
display_autnum(json_data, config, data_tree) click to toggle source
# File lib/nicinfo/autnum.rb, line 24
def NicInfo.display_autnum json_data, config, data_tree
  autnum = config.factory.new_autnum.process( json_data )
  NicInfo::display_object_with_entities( autnum, config, data_tree )
end
display_domain(json_data, config, data_node) click to toggle source
# File lib/nicinfo/domain.rb, line 27
def NicInfo.display_domain json_data, config, data_node
  obj_array = json_data
  unless json_data.instance_of? Array
    obj_array = Array.new
    obj_array << json_data
  end
  respObjs = ResponseObjSet.new config
  obj_array.each do |array_object|
    domain = config.factory.new_domain.process( array_object )
    root = domain.to_node
    data_node.add_root( root )
    if !domain.entities.empty? or !domain.nameservers.empty?
      domain.ds_data_objs.each do |ds|
        ds_node = ds.to_node
        root.add_child( ds_node )
      end
      domain.key_data_objs.each do |key|
        key_node = key.to_node
        root.add_child( key_node )
      end
      NicInfo::add_entity_nodes( domain.entities, root )
      domain.nameservers.each do |ns|
        ns_node = ns.to_node
        root.add_child( ns_node )
        NicInfo::add_entity_nodes( ns.entities, ns_node )
      end
    end
    if domain.network
      net_node = domain.network.to_node
      root.add_child net_node
      NicInfo::add_entity_nodes( domain.network.entities, net_node )
    end
    respObjs.add domain
    domain.ds_data_objs.each do |ds|
      respObjs.add ds
    end
    domain.key_data_objs.each do |key|
      respObjs.add key
    end
    NicInfo::add_entity_respobjs( domain.entities, respObjs )
    respObjs.associateEntities domain.entities
    domain.nameservers.each do |ns|
      respObjs.add ns
      NicInfo::add_entity_respobjs( ns.entities, respObjs )
      respObjs.associateEntities ns.entities
    end
    if domain.network
      respObjs.add domain.network
      NicInfo::add_entity_respobjs( domain.network.entities, respObjs )
    end
  end
  data_node.to_normal_log( config.logger, true )
  respObjs.display
end
display_domains(json_data, config, data_tree) click to toggle source
# File lib/nicinfo/domain.rb, line 82
def NicInfo.display_domains json_data, config, data_tree
  domain_array = json_data[ "domainSearchResults" ]
  if domain_array != nil
    if domain_array.instance_of? Array
      NicInfo.display_domain( domain_array, config, data_tree )
    else
      config.conf_msgs << "'domainSearchResults' is not an array"
    end
  else
    config.conf_msgs << "'domainSearchResults' is not present"
  end
end
display_ds_data(json_data, config, data_node) click to toggle source
# File lib/nicinfo/ds_data.rb, line 23
def NicInfo.display_ds_data json_data, config, data_node
  ds_data = DsData.new( config ).process( json_data ).display
end
display_entities(json_data, config, data_tree) click to toggle source
# File lib/nicinfo/entity.rb, line 61
def NicInfo.display_entities json_data, config, data_tree
  entity_array = json_data[ "entitySearchResults" ]
  if entity_array != nil
    if entity_array.instance_of? Array
      display_array = Array.new
      entity_array.each do |ea|
        entity = config.factory.new_entity.process( ea )
        display_array << entity
      end
      NicInfo.display_object_with_entities( display_array, config, data_tree )
    else
      config.conf_msgs << "'entitySearchResults' is not an array"
    end
  else
    config.conf_msgs << "'entitySearchResults' is not present"
  end
end
display_entity(json_data, config, data_tree) click to toggle source
# File lib/nicinfo/entity.rb, line 23
def NicInfo.display_entity json_data, config, data_tree
  entity = config.factory.new_entity.process( json_data )

  respobjs = ResponseObjSet.new config
  root = entity.to_node
  data_tree.add_root( root )
  if !entity.entities.empty?
    NicInfo::add_entity_nodes( entity.entities, root )
  end
  entity.networks.each do |network|
    net_node = network.to_node
    root.add_child( net_node )
    NicInfo::add_entity_nodes( network.entities, net_node )
  end
  entity.autnums.each do |autnum|
    as_node = autnum.to_node
    root.add_child( as_node )
    NicInfo::add_entity_nodes( autnum.entities, as_node )
  end

  respobjs.add entity
  NicInfo::add_entity_respobjs( entity.entities, respobjs )
  respobjs.associateEntities entity.entities
  entity.networks.each do |network|
    respobjs.add network
    NicInfo::add_entity_respobjs( network.entities, respobjs )
    respobjs.associateEntities network.entities
  end
  entity.autnums.each do |autnum|
    respobjs.add autnum
    NicInfo::add_entity_respobjs( autnum.entities, respobjs )
    respobjs.associateEntities autnum.entities
  end

  data_tree.to_normal_log( config.logger, true )
  respobjs.display
end
display_ip(json_data, config, data_tree) click to toggle source
# File lib/nicinfo/ip.rb, line 27
def NicInfo.display_ip json_data, config, data_tree
  ip = config.factory.new_ip.process( json_data )
  NicInfo::display_object_with_entities( ip, config, data_tree )
end
display_key_data(json_data, config, data_node) click to toggle source
# File lib/nicinfo/key_data.rb, line 23
def NicInfo.display_key_data json_data, config, data_node
  key_data = KeyData.new( config ).process( json_data ).display
end
display_nameservers(json_data, config, data_node) click to toggle source
# File lib/nicinfo/ns.rb, line 29
def NicInfo.display_nameservers json_data, config, data_node
  ns_array = json_data[ "nameserverSearchResults" ]
  if ns_array != nil
    if ns_array.instance_of? Array
      display_array = Array.new
      ns_array.each do |ea|
        ns = config.factory.new_ns.process( ea )
        display_array << ns
      end
      NicInfo::display_object_with_entities( display_array, config, data_node )
    else
      config.conf_msgs << "'nameserverSearchResults' is not an array"
    end
  else
    config.conf_msgs << "'nameserverSearchResults' is not present"
  end
end
display_ns(json_data, config, data_node) click to toggle source
# File lib/nicinfo/ns.rb, line 24
def NicInfo.display_ns json_data, config, data_node
  ns = config.factory.new_ns.process( json_data )
  NicInfo::display_object_with_entities( ns, config, data_node )
end
display_object_with_entities(object, config, data_node) click to toggle source
# File lib/nicinfo/common_json.rb, line 23
def NicInfo.display_object_with_entities object, config, data_node
  obj_array = object
  unless object.instance_of? Array
    obj_array = Array.new
    obj_array << object
  end
  respobjs = ResponseObjSet.new config
  obj_array.each do |array_object|
    root = array_object.to_node
    data_node.add_root( root )
    if !array_object.entities.empty?
      NicInfo::add_entity_nodes( array_object.entities, root )
    end
    respobjs.add array_object
    NicInfo::add_entity_respobjs( array_object.entities, respobjs )
    respobjs.associateEntities array_object.entities
  end
  data_node.to_normal_log( config.logger, true )
  respobjs.display
end
get_algorithm(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 51
def NicInfo.get_algorithm json_data
  return json_data[ "algorithm" ]
end
get_autnums(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 104
def NicInfo.get_autnums json_data
  return json_data[ "autnums" ]
end
get_country(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 136
def NicInfo.get_country json_data
  return json_data[ "country" ]
end
get_descriptions(json_data, config) click to toggle source
# File lib/nicinfo/utils.rb, line 77
def NicInfo.get_descriptions json_data, config
  return if !json_data
  if json_data.instance_of?( Hash )
    retval = json_data[ "description" ]
    unless retval.instance_of?( Array )
      config.conf_msgs << "'description' is not an array."
      retval = nil
    end
  else
    config.conf_msgs << "expected object for 'remarks' or 'notices'."
    retval = nil
  end
  return retval
end
get_ds_data_objs(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 33
def NicInfo.get_ds_data_objs json_data
  secure_dns = NicInfo::get_secure_dns json_data
  if secure_dns.instance_of? Array
    secure_dns = secure_dns[ 0 ]
  end
  return secure_dns[ "dsData" ] if secure_dns
  return nil
end
get_endAddress(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 116
def NicInfo.get_endAddress json_data
  return json_data[ "endAddress" ]
end
get_endAutnum(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 124
def NicInfo.get_endAutnum json_data
  return json_data[ "endAutnum" ]
end
get_entitites(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 92
def NicInfo.get_entitites json_data
  return json_data[ "entities" ]
end
get_handle(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 55
def NicInfo.get_handle json_data
  return json_data[ "handle" ]
end
get_key_data_objs(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 42
def NicInfo.get_key_data_objs json_data
  secure_dns = NicInfo::get_secure_dns json_data
  if secure_dns.instance_of? Array
    secure_dns = secure_dns[ 0 ]
  end
  return secure_dns[ "keyData" ] if secure_dns
  return nil
end
get_ldhName(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 69
def NicInfo.get_ldhName json_data
  return json_data[ "ldhName" ]
end
get_name(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 128
def NicInfo.get_name json_data
  return json_data[ "name" ]
end
get_nameservers(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 108
def NicInfo.get_nameservers json_data
  return json_data[ "nameservers" ]
end
get_network(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 100
def NicInfo.get_network json_data
  return json_data[ "network" ]
end
get_networks(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 96
def NicInfo.get_networks json_data
  return json_data[ "networks" ]
end
get_object_class_name(json_data, expected, config) click to toggle source
# File lib/nicinfo/utils.rb, line 59
def NicInfo.get_object_class_name json_data, expected, config
  objectClassName =  json_data[ "objectClassName" ]
  if objectClassName == nil
    config.conf_msgs << "Expected 'objectClassName' is not present."
  elsif objectClassName != expected
    config.conf_msgs << "Expected 'objectClassName' to be '#{expected}' but it is '#{objectClassName}'."
  end
  return objectClassName
end
get_secure_dns(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 29
def NicInfo.get_secure_dns json_data
  return json_data[ "secureDNS" ]
end
get_startAddress(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 112
def NicInfo.get_startAddress json_data
  return json_data[ "startAddress" ]
end
get_startAutnum(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 120
def NicInfo.get_startAutnum json_data
  return json_data[ "startAutnum" ]
end
get_type(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 132
def NicInfo.get_type json_data
  return json_data[ "type" ]
end
get_unicodeName(json_data) click to toggle source
# File lib/nicinfo/utils.rb, line 73
def NicInfo.get_unicodeName json_data
  return json_data[ "unicodeName" ]
end
is_female_name(name) click to toggle source
# File lib/nicinfo/common_names.rb, line 26
def NicInfo::is_female_name name
  is_name "female-first-names.txt", name
end
is_last_name(name) click to toggle source
# File lib/nicinfo/common_names.rb, line 18
def NicInfo::is_last_name name
  is_name "last-names.txt", name
end
is_male_name(name) click to toggle source
# File lib/nicinfo/common_names.rb, line 22
def NicInfo::is_male_name name
  is_name "male-first-names.txt", name
end
is_name(file_name, name) click to toggle source
# File lib/nicinfo/common_names.rb, line 30
def NicInfo::is_name file_name, name
  retval = false
  name.gsub! '*',''
  names = name.split( ' ' )

  file = File.new( File.join( File.dirname( __FILE__ ) , file_name ), "r" )
  file.each_line do |line|
    names.each do |n|
      if line.start_with?( n )
        retval = true
        break
      end
    end
  end
  file.close

  return retval
end
make_safe( url ) click to toggle source
# File lib/nicinfo/utils.rb, line 22
def NicInfo.make_safe( url )
  p = URI::Parser.new
  safe = p.escape( url )
  safe = p.escape( safe, "!*'();:@&=+$,/?#[]" )
  return safe
end
random_port() click to toggle source
# File lib/nicinfo/traceroute.rb, line 36
def NicInfo.random_port
  1024 + rand(64511)
end
traceroute(host, config) click to toggle source
# File lib/nicinfo/traceroute.rb, line 40
def NicInfo.traceroute host, config
  ips = Array.new

  begin
    myname = Socket.gethostname
  rescue SocketError => err_msg
    config.logger.mesg "Can't get my own host name (#{err_msg})."
    exit 1
  end

  config.logger.mesg "Tracing route to #{host}"

  ttl                     = 1
  max_ttl                 = 255
  max_contiguaous_timeout = 16
  localport               = random_port
  dgram_sock              = UDPSocket::new

  begin
    dgram_sock.bind( myname, localport )
  rescue
    localport = random_port
    retry
  end

  begin
    icmp_sock     = Socket.open( Socket::PF_INET, Socket::SOCK_RAW, Socket::IPPROTO_ICMP )
    icmp_sockaddr = Socket.pack_sockaddr_in( localport, myname )
    icmp_sock.bind( icmp_sockaddr )
  rescue SystemCallError => socket_error
    config.logger.mesg "Error with ICMP socket. You probably need to be root: #{socket_error}"
    exit 1
  end


  begin
    dgram_sock.connect( host, 999 )
  rescue SocketError => err_msg
    config.logger.mesg "Can't connect to remote host (#{err_msg})."
    exit 1
  end

  stop_tracing = false
  continguous_timeout = 0
  until stop_tracing
    dgram_sock.setsockopt( 0, Socket::IP_TTL, ttl )
    dgram_sock.send( "RubyRoute says hello!", 0 )

    begin
      Timeout::timeout( 1 ) {
        data, sender = icmp_sock.recvfrom( 8192 )
        # 20th and 21th bytes of IP+ICMP datagram carry the ICMP type and code resp.
        icmp_type = data.unpack( '@20C' )[0]
        icmp_code = data.unpack( '@21C' )[0]
        # Extract the ICMP sender from response.
        ip = Socket.unpack_sockaddr_in( sender )[1].to_s
        ips << ip
        config.logger.mesg "TTL = #{ttl}:  " + ip
        continguous_timeout = 0
        if ( icmp_type == 3 and icmp_code == 13 )
          config.logger.mesg "'Communication Administratively Prohibited' from this hop."
          # ICMP 3/3 is port unreachable and usually means that we've hit the target.
        elsif ( icmp_type == 3 and icmp_code == 3 )
          config.logger.mesg "Destination reached. Trace complete."
          stop_tracing = true
        end
      }
    rescue Timeout::Error
      config.logger.mesg "Timeout error with TTL = #{ttl}!"
      continguous_timeout += 1
    end

    ttl += 1
    stop_tracing = true if ttl > max_ttl
    if continguous_timeout > max_contiguaous_timeout
      stop_tracing = true
      config.logger.mesg "Getting a lot of contiguous timeouts. Prematurely terminating trace."
    end
  end

  ips
end