Module 0x3 | Network Kung Fu

    • Calculating network prefix of an IP address from IP address and subnet mask.
    • Calculating the host part of an IP address from IP address and subnet mask.
    • Calculating the number of hosts in a subnet.
    • Check whether an IP address belongs to a subnet or not.
    • Converting subnet mask from dot-decimal notation to integer.

    Ruby provides class(IPAddr) for basic operations on IP address that can be used to perform all operations mentioned above.

    A simple mask method call will give us the network prefix part of IP address. It is simply a bitwise mask of IP address with subnet mask.

    1. ip = IPAddr.new(ARGV[0])
    2. network_prefix = ip.mask(ARGV[1])
    3. puts network_prefix

    Run it

    1. ruby ip_example.rb 192.168.5.130 24
    2. # Returns
    3. 192.168.5.0

    Calculating the host part of an IP address from IP address and subnet mask.

    calculating the host part is not as trivial as the network part of the IP address. We first calculate the complement of subnet mask.

    Subnet(24) : 11111111.11111111.11111111.00000000

    neg_subnet(24) : 00000000.00000000.00000000.11111111

    1. require 'ipaddr'
    2. ip = IPAddr.new(ARGV[0])
    3. host = ip & neg_subnet
    4. puts host

    Run it

    1. ruby ip_example.rb 192.168.5.130 24
    2. # Returns
    3. 0.0.0.130

    We used to_range method to create a range of all the IPs then count method to count the IPs in range. We reduced the number by two to exclude the gateway and broadcast IP address.

    1. require 'ipaddr'
    2. ip=IPAddr.new("0.0.0.0/#{ARGV[0]}")
    3. puts ip.to_range.count-2

    Run it

    Check whether an IP address belong to a subnet or not.

    === is an alias of include? which returns true if ip address belongs to the range otherwise it returns false.

    1. require 'ipaddr'
    2. puts net === ARGV[2]

    Run it

    1. ruby ip_example.rb 192.168.5.128 24 192.168.5.93
    2. true
    1. ruby ip_example.rb 192.168.5.128 24 192.168.6.93
    2. false

    We treated subnet mask as ip address and converted it into an integer by using to_i then used to_s(2) to convert the integer into binary form. Once we had the binary we counted the number of occurrence of digit 1 with count("1").

    1. require 'ipaddr'
    2. subnet_mask = IPAddr.new(ARGV[0])
    3. puts subnet_mask.to_i.to_s(2).count("1").to_s
    1. ruby ip_example.rb 255.255.255.0
    2. 24

    Converting IP to another formats

    IP Decimal to Dotted notation

    or

    1. [3232236159].pack('N').unpack('C4').join('.')

    IP Dotted notation to Decimal

    1. require 'ipaddr'
    2. IPAddr.new('192.168.2.127').to_i

    This part has been pretty quoted from topic

    IP Geolocation

    you may need to know more information about IP location due attack investigation or any other reason.

    The special thing about geoip lib is that it’s an API for offline database you download from www.maxmind.com. There are few free databases from MaxMind whoever you can have a subscription database version though.

    • Download one of the free GeoLite country, city or ASN databases
    • Install geoip gem

      1. gem install geoip
    • Usage

    1. #!/usr/bin/env ruby
    2. geoip = GeoIP.new('GeoLiteCity.dat')
    3. geoinfo = geoip.country(ip).to_hash
    4. puts "IP address:\t" + geoinfo[:ip]
    5. puts "Country:\t" + geoinfo[:country_name]
    6. puts "Country code:\t" + geoinfo[:country_code2]
    7. puts "City name:\t" + geoinfo[:city_name]
    8. puts "Latitude:\t" + geoinfo[:latitude]
    9. puts "Longitude:\t" + geoinfo[:longitude]
    10. puts "Time zone:\t" + geoinfo[:timezone]
    1. -> ruby ip2location.rb 108.168.255.243
    2. IP address: 108.168.255.243
    3. Country: United States
    4. Country code: US
    5. City name: Dallas
    6. Latitude: 32.9299
    7. Longitude: -96.8353