Class: Ronin::Support::Network::IP

Inherits:
IPAddr
  • Object
show all
Defined in:
lib/ronin/support/network/ip.rb,
lib/ronin/support/network/ip/mixin.rb

Overview

Represents a single IP address.

Examples

ip = IP.new('192.30.255.113')

Reverse DNS lookup:

ip.get_name
# => "lb-192-30-255-113-sea.github.com"
ip.get_names
# => ["lb-192-30-255-113-sea.github.com"]
ip.get_host
# => #<Ronin::Support::Network::Host: lb-192-30-255-113-sea.github.com>
ip.get_hosts
# => [#<Ronin::Support::Network::Host: lb-192-30-255-113-sea.github.com>]
ip.host
# => #<Ronin::Support::Network::Host: lb-192-30-255-113-sea.github.com>
ip.hosts
# => [#<Ronin::Support::Network::Host: lb-192-30-255-113-sea.github.com>]

Get ASN information:

ip.asn
# => #<Ronin::Support::Network::ASN::DNSRecord:0x00007f34142de598
#     @country_code="US",
#     @name=nil,
#     @number=15133,
#     @range=#<Ronin::Support::Network::IPRange::CIDR: 93.184.216.0/24>>

Since:

  • 1.0.0

Defined Under Namespace

Modules: Mixin

Constant Summary collapse

REGEX =

A regular expression for matching IP addresses.

Since:

  • 1.1.0

/#{RE_IPV4ADDRLIKE}|#{RE_IPV6ADDRLIKE_FULL}|#{RE_IPV6ADDRLIKE_COMPRESSED}/
IPINFO_URI =

The URI for https://ipinfo.io/ip

Since:

  • 1.0.0

URI::HTTPS.build(host: 'ipinfo.io', path: '/ip')

Constants inherited from IPAddr

IPAddr::MASKS

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from IPAddr

#each

Methods included from Enumerable

#map_hash

Constructor Details

#initialize(address, family = Socket::AF_UNSPEC) ⇒ IP

Note:

If the IP address has an %iface suffix, it will be removed from the IP address.

Initializes the IP address.

Examples:

ip = IP.new('192.30.255.113')

Parameters:

  • address (String)

    The address of the IP.

  • family (Integer) (defaults to: Socket::AF_UNSPEC)

    The address family for the CIDR range. This is mainly for backwards compatibility with IPAddr#initialize.

Raises:

  • (InvalidIP)

    The given address is not a valid IP address.

Since:

  • 1.0.0



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/ronin/support/network/ip.rb', line 94

def initialize(address,family=Socket::AF_UNSPEC)
  case address
  when String
    # XXX: remove the %iface suffix for ruby < 3.1.0
    if address =~ /%.+$/
      address = address.sub(/%.+$/,'')
    end

    # pre-cache the given IP address String
    @address = address
  end

  begin
    super(address,family)
  rescue IPAddr::InvalidAddressError
    raise(InvalidIP,"invalid IP address: #{address.inspect}")
  end
end

Class Method Details

.extract(text, version = nil) {|ip| ... } ⇒ Array<String>

Extracts IP Addresses from text.

Examples:

IPAddr.extract("Host: 127.0.0.1\n\rHost: 10.1.1.1\n\r")
# => ["127.0.0.1", "10.1.1.1"]

Extract only IPv4 addresses from a large amount of text:

IPAddr.extract(text,:v4) do |ip|
  puts ip
end

Parameters:

  • text (String)

    The text to scan for IP Addresses.

  • version (4, :v4, :ipv4, 6, :v6, :ipv6) (defaults to: nil)

    The version of IP Address to extract.

Yields:

  • (ip)

    The given block will be passed each extracted IP Address.

Yield Parameters:

  • ip (String)

    An IP Address from the text.

Returns:

  • (Array<String>)

    The IP Addresses found in the text.

Since:

  • 1.0.0



261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/ronin/support/network/ip.rb', line 261

def self.extract(text,version=nil,&block)
  return enum_for(__method__,text,version).to_a unless block_given?

  regexp = case version
           when :ipv4, :v4, 4 then Text::Patterns::IPV4_ADDR
           when :ipv6, :v6, 6 then Text::Patterns::IPV6_ADDR
           else                    Text::Patterns::IP_ADDR
           end

  text.scan(regexp,&block)
  return nil
end

.local_addressString

Determines the local IP address.

Examples:

IP.local_address
# => "127.0.0.1"

Returns:

Since:

  • 1.0.0



217
218
219
# File 'lib/ronin/support/network/ip.rb', line 217

def self.local_address
  Socket.ip_address_list.first.ip_address
end

.local_addressesArray<String>

Determines all local IP addresses.

Examples:

IP.local_addresses
# => ["127.0.0.1", "192.168.1.42", "::1", "fe80::4ba:612f:9e2:37e2"]

Returns:

Since:

  • 1.0.0



180
181
182
183
184
185
186
187
188
189
190
# File 'lib/ronin/support/network/ip.rb', line 180

def self.local_addresses
  Socket.ip_address_list.map do |addrinfo|
    address = addrinfo.ip_address

    if address =~ /%.+$/
      address = address.sub(/%.+$/,'')
    end

    address
  end
end

.local_ipIP

Determines the local IP.

Examples:

IP.local_ip
# => #<Ronin::Support::Network::IP: 127.0.0.1>

Returns:

Since:

  • 1.0.0



230
231
232
# File 'lib/ronin/support/network/ip.rb', line 230

def self.local_ip
  new(local_address)
end

.local_ipsArray<IP>

Determines all local IPs.

Examples:

IP.local_ips
# => [#<Ronin::Support::Network::IP: 127.0.0.1>,
      #<Ronin::Support::Network::IP: 192.168.1.42>,
      #<Ronin::Support::Network::IP: ::1>,
      #<Ronin::Support::Network::IP: fe80::04ba:612f:09e2:37e2>]

Returns:

Since:

  • 1.0.0



204
205
206
# File 'lib/ronin/support/network/ip.rb', line 204

def self.local_ips
  local_addresses.map(&method(:new))
end

.public_addressString?

Determines the current public IP address.

Returns:

Since:

  • 1.0.0



147
148
149
150
151
152
153
154
155
156
157
# File 'lib/ronin/support/network/ip.rb', line 147

def self.public_address
  response = begin
               Net::HTTP.get_response(IPINFO_URI)
             rescue
               # ignore any network failures
             end

  if response && response.code == '200'
    return response.body
  end
end

.public_ipIP?

Determines the current public IP.

Returns:

Since:

  • 1.0.0



165
166
167
168
169
# File 'lib/ronin/support/network/ip.rb', line 165

def self.public_ip
  if (address = public_address)
    new(address)
  end
end

Instance Method Details

#addressString

The IP address.

Returns:

  • (String)

    The String version of the IP address.

Since:

  • 1.0.0



321
322
323
# File 'lib/ronin/support/network/ip.rb', line 321

def address
  @address ||= to_s
end

#asnASN::Record

The Autonomous System Number (ASN) information for the IP address.

Examples:

ip = IP.new('93.184.216.34')
ip.asn
# => #<Ronin::Support::Network::ASN::DNSRecord:0x00007f34142de598
      @country_code="US",
      @name=nil,
      @number=15133,
      @range=#<Ronin::Support::Network::IPRange::CIDR: 93.184.216.0/24>>

Returns:

Since:

  • 1.0.0



339
340
341
# File 'lib/ronin/support/network/ip.rb', line 339

def asn
  @asn ||= ASN.query(self)
end

#broadcast?Boolean

Determines if the address is a IPv4 broadcast addresses.

Examples:

ip = IPAddr.new('255.255.255.255')
ip.broadcast?
# => true
ip = IPAddr.new('192.168.1.255')
ip.broadcast?
# => true
ip = IPAddr.new('1.1.1.1')
ip.broadcast?
# => false

Returns:

  • (Boolean)

Since:

  • 1.0.0



290
291
292
293
# File 'lib/ronin/support/network/ip.rb', line 290

def broadcast?
  # NOTE: IPv6 does not have broadcast addresses
  ipv4? && (@addr & 0xff) == 0xff
end

#get_host(**kwargs) ⇒ Host?

Looks up the host for the IP.

Examples:

ip = IP.new('192.30.255.113')
ip.get_host
# => #<Ronin::Support::Network::Host: lb-192-30-255-113-sea.github.com>

Parameters:

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.

  • [Array<String>, (Hash)

    a customizable set of options

  • [String, (Hash)

    a customizable set of options

Returns:

  • (Host, nil)

    The host for the IP.

Since:

  • 1.0.0



413
414
415
416
417
# File 'lib/ronin/support/network/ip.rb', line 413

def get_host(**kwargs)
  if (name = get_name(**kwargs))
    Host.new(name)
  end
end

#get_hosts(**kwargs) ⇒ Array<Host>

Looks up all hosts associated with the IP.

Examples:

ip = IP.new('192.30.255.113')
ip.get_hosts
# => [#<Ronin::Support::Network::Host: lb-192-30-255-113-sea.github.com>]

Parameters:

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.

  • [Array<String>, (Hash)

    a customizable set of options

  • [String, (Hash)

    a customizable set of options

Returns:

Since:

  • 1.0.0



439
440
441
# File 'lib/ronin/support/network/ip.rb', line 439

def get_hosts(**kwargs)
  get_names(**kwargs).map { |name| Host.new(name) }
end

#get_name(**kwargs) ⇒ String? Also known as: reverse_lookup

Looks up the hostname of the address.

Examples:

ip = IP.new('192.30.255.113')
ip.get_name
# => "lb-192-30-255-113-sea.github.com"

Parameters:

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.

  • [Array<String>, (Hash)

    a customizable set of options

  • [String, (Hash)

    a customizable set of options

Returns:

  • (String, nil)

    The hostname of the address.

Since:

  • 1.0.0



363
364
365
# File 'lib/ronin/support/network/ip.rb', line 363

def get_name(**kwargs)
  DNS.get_name(@address,**kwargs)
end

#get_names(**kwargs) ⇒ Array<String>

Looks up all hostnames associated with the IP.

Examples:

ip = IP.new('192.30.255.113')
ip.get_names
# => ["lb-192-30-255-113-sea.github.com"]

Parameters:

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.

  • [Array<String>, (Hash)

    a customizable set of options

  • [String, (Hash)

    a customizable set of options

Returns:

Since:

  • 1.0.0



389
390
391
# File 'lib/ronin/support/network/ip.rb', line 389

def get_names(**kwargs)
  DNS.get_names(@address,**kwargs)
end

#get_ptr_name(**kwargs) ⇒ String?

Queries the PTR host name for the IP address.

Parameters:

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.

  • [Array<String>, (Hash)

    a customizable set of options

  • [String, (Hash)

    a customizable set of options

Returns:

  • (String, nil)

    The host name that points to the given IP.

Since:

  • 1.0.0



513
514
515
# File 'lib/ronin/support/network/ip.rb', line 513

def get_ptr_name(**kwargs)
  DNS.get_ptr_name(@address,**kwargs)
end

#get_ptr_names(**kwargs) ⇒ Array<String>

Queries all PTR names for the IP address.

Parameters:

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.

  • [Array<String>, (Hash)

    a customizable set of options

  • [String, (Hash)

    a customizable set of options

Returns:

Since:

  • 1.0.0



553
554
555
# File 'lib/ronin/support/network/ip.rb', line 553

def get_ptr_names(**kwargs)
  DNS.get_ptr_names(@address,**kwargs)
end

#get_ptr_record(**kwargs) ⇒ Resolv::DNS::Resource::PTR?

Queries the first PTR DNS record for the IP address.

Parameters:

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.

  • [Array<String>, (Hash)

    a customizable set of options

  • [String, (Hash)

    a customizable set of options

Returns:

  • (Resolv::DNS::Resource::PTR, nil)

    The first PTR DNS record of the host name or nil if the host name has no PTR records.

See Also:

Since:

  • 1.0.0



494
495
496
# File 'lib/ronin/support/network/ip.rb', line 494

def get_ptr_record(**kwargs)
  DNS.get_ptr_record(@address,**kwargs)
end

#get_ptr_records(**kwargs) ⇒ Array<Resolv::DNS::Resource::PTR>

Queries all PTR DNS records for the IP address.

Parameters:

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.

  • [Array<String>, (Hash)

    a customizable set of options

  • [String, (Hash)

    a customizable set of options

Returns:

  • (Array<Resolv::DNS::Resource::PTR>)

    All PTR DNS records for the given IP.

See Also:

Since:

  • 1.0.0



534
535
536
# File 'lib/ronin/support/network/ip.rb', line 534

def get_ptr_records(**kwargs)
  DNS.get_ptr_records(@address,**kwargs)
end

#hostHost?

The primary host name of the address.

Examples:

ip = IP.new('192.30.255.113')
ip.host
# => #<Ronin::Support::Network::Host: lb-192-30-255-113-sea.github.com>

Returns:

  • (Host, nil)

    The host name or nil if the IP address has no host names.

Since:

  • 1.0.0



472
473
474
# File 'lib/ronin/support/network/ip.rb', line 472

def host
  hosts.first
end

#hostsArray<Host>

Note:

This method returns memoized data.

The host names of the address.

Examples:

ip = IP.new('192.30.255.113')
ip.hosts
# => [#<Ronin::Support::Network::Host: lb-192-30-255-113-sea.github.com>]

Returns:

  • (Array<Host>)

    The host names of the address or an empty Array if the IP address has no host names.

Since:

  • 1.0.0



457
458
459
# File 'lib/ronin/support/network/ip.rb', line 457

def hosts
  @hosts ||= get_hosts
end

#inspectString

Inspects the IP.

Returns:

  • (String)

    The inspected IP object.

Since:

  • 1.0.0



603
604
605
# File 'lib/ronin/support/network/ip.rb', line 603

def inspect
  "#<#{self.class}: #{address}>"
end

#ipv4Object

Note:

[IP] If the IP address is an IPv4-mapped IPv6 address then the IPv6 address will be extracted from the IPv6 address. If the IP address is a regular IPv4 address, then the IP address will be returned.

Converts the IP address to it's IPv4 version.

Examples:

Converting an IPv4-mapped IPv6 address to an IPv4 address:

ip = Network::IP.new('::ffff:127.0.0.1')
ip.ipv4
# => #<Ronin::Support::Network::IP: 127.0.0.1>

When the IP address is already an IPv4 address:

ip = Network::IP.new('127.0.0.1')
ip.ipv4
# => #<Ronin::Support::Network::IP: 127.0.0.1>

Raises:

  • (InvalidIP)

    The IP address was a regular IPv6 address and cannot be converted to a smaller IPv4 address.

Since:

  • 1.1.0



581
582
583
584
585
586
587
588
589
590
591
# File 'lib/ronin/support/network/ip.rb', line 581

def ipv4
  if ipv6?
    if ipv4_mapped?
      self.class.new(to_i & 0xffffffff,Socket::AF_INET)
    else
      raise(InvalidIP,"cannot convert a regular IPv6 address to an IPv4 address: #{inspect}")
    end
  else
    self
  end
end

#logical?Boolean

Determines if the address is a "logical" IPv4 address.

Examples:

ip = IPAddr.new('0.0.0.0')
ip.logical?
# => true
ip = IPAddr.new('192.168.1.0')
ip.logical?
# => true
ip = IPAddr.new('1.1.1.1')
ip.logical?
# => false

Returns:

  • (Boolean)

Since:

  • 1.0.0



311
312
313
# File 'lib/ronin/support/network/ip.rb', line 311

def logical?
  ipv4? && (@addr & 0xff) == 0x00
end

#set(addr, *family) ⇒ self (protected)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Sets the IP address using the numeric IP address value.

Parameters:

  • addr (Integer)

    The new numeric IP address value.

  • family (Integer)

    Optional IP address family.

Returns:

  • (self)

Since:

  • 1.0.0



128
129
130
131
132
133
134
# File 'lib/ronin/support/network/ip.rb', line 128

def set(addr,*family)
  super(addr,*family)

  # unset the cached IP address since the numeric address has changed
  @address = nil
  return self
end