IP address manipulation library
Ruby
Latest commit 8e71d7f Jan 23, 2015 @deploy2 Merge pull request #18 from chrismar035/patch-1
Add license to gemspec
Permalink
Failed to load latest commit information.
lib Factor out the ARPA suffix into a constant Oct 3, 2014
test Put assert_equal the right way round Oct 3, 2014
.gitignore
.travis.yml Update Gemfile to reference gemspec. Add development dependencies to … Aug 31, 2014
COPYING.txt Add distribution terms Jan 26, 2010
Gemfile Update Gemfile to reference gemspec. Add development dependencies to … Aug 31, 2014
LICENSE.txt Add distribution terms Jan 26, 2010
README.rdoc updated readme Nov 14, 2013
Rakefile Assorted changes to reduce the number of Rubocop violations. No chang… Sep 5, 2014
ruby-ip.gemspec Add license to gemspec Jan 22, 2015

README.rdoc

ruby-ip library

This is a library for manipulating IP addresses.

Installation

Gem

gem install ruby-ip

Source

git clone git://github.com/deploy2/ruby-ip.git

Docs

deploy2.github.com/ruby-ip/

Feature overview

  • Create from string and to string

    require 'ip'
    ip = IP.new("192.0.2.53/24")
    ip.to_s       # "192.0.2.53/24"
    ip.to_i       # 3221226037
    ip.to_b       # 11000000000000000000001000110101
    ip.to_hex     # "c0000235"
    ip.to_addr    # "192.0.2.53"
    ip.to_arpa    # "53.2.0.192.in-addr.arpa."
    ip.pfxlen     # 24
  • Qualify IP address with “routing context” (VRF)

    ip = IP.new("192.0.2.53/24@cust1")
    ip.to_s       # "192.0.2.53/24@cust1"
    ip.to_addrlen # "192.0.2.53/24"
    ip.ctx        # "cust1"
  • Clean implementation of IP::V4 and IP::V6 as subclasses of IP

    ip1 = IP.new("192.0.2.53/24")       #<IP::V4 192.0.2.53/24>
    ip2 = IP.new("2001:db8:be00::/48")  #<IP::V6 2001:db8:be00::/48>
    ip1.is_a?(IP::V4)                   # true
  • Create directly from integers or hex

    ip = IP::V4.new(3221226037, 24, "cust1")
    ip = IP::V4.new("c0000235", 24, "cust1")
  • Netmask manipulation

    ip = IP.new("192.0.2.53/24")
    ip.network         #<IP::V4 192.0.2.0/24>
    ip.network(1)      #<IP::V4 192.0.2.1/24>
    ip.broadcast       #<IP::V4 192.0.2.255/24>
    ip.broadcast(-1)   #<IP::V4 192.0.2.254/24>
    ip.mask            # 255
    ip.size            # 256
    ip.netmask.to_s    # "255.255.255.0"
    ip.wildmask.to_s   # "0.0.0.255"
  • Address masking

    ip = IP.new("192.0.2.53/24")
    ip.offset?         # true
    ip.offset          # 53
    ip.mask!
    ip.to_s            # "192.0.2.0/24"
    ip.offset?         # false
  • Simple IP arithmetic

    ip = IP.new("192.0.2.53/24")
    ip + 4             #<IP::V4 192.0.2.57/24>
    ip | 7             #<IP::V4 192.0.2.55/24>
    ip ^ 7             #<IP::V4 192.0.2.50/24>
    ~ip                #<IP::V4 63.255.253.202/24>
  • Advanced Subnet Operations

    sn = IP.new('192.168.0.0/24')
    ip = IP.new('192.168.0.48/32')
    sn.split                    [#<IP::V4 192.168.0.0/25>, 
                                #<IP::V4 192.168.0.128/25>] (2 evenly divided subnets)
    sn.divide_by_subnets(3)     [#<IP::V4 192.168.0.0/26>, 
                                #<IP::V4 192.168.0.64/26>, 
                                #<IP::V4 192.168.0.128/26>, 
                                #<IP::V4 192.168.0.192/26>] (4 evenly divided subnets)
    #keep in mind this always takes into account a network and broadcast address
    sn.divide_by_hosts(100)     [#<IP::V4 192.168.0.0/25>, 
                                #<IP::V4 192.168.0.128/25>] (128 hosts each)
    ip = IP.new('192.168.0.48/32')
    ip.is_in?(sn)
    => true
  • Convert to and from a compact Array representation

    ip1 = IP.new("192.0.2.53/24@cust1")
    ip1.to_a     # ["v4", 3221226037, 24, "cust1"]
    
    ip2 = IP.new(["v4", 3221226037, 24, "cust1"])
    ip1 == ip2   # true
  • Hex array representation, useful when talking to languages which don't have Bignum support

    ip1 = IP.new("2001:db8:be00::/48@cust1")
    ip1.to_ah    # ["v6", "20010db8be0000000000000000000000", 48, "cust1"]
    
    ip2 = IP.new(["v6", "20010db8be0000000000000000000000", 48, "cust1"])
    ip1 == ip2   # true
  • Addresses are Comparable, sortable, and can be used as Hash keys

Why not IPAddr?

Ruby bundles an IPAddr class (ipaddr.rb). However there are a number of serious problems with this library.

  1. Given an IP address with a netmask or prefix (e.g. 192.0.2.0/24) it's very hard to get access to the netmask part. It involves digging around instance variables.

  2. It's impossible to deal with an off-base address with prefix, because IPAddr forcibly masks it to the base. e.g. 192.0.2.53/24 is stored as 192.0.2.0/24

  3. IPAddr uses calls to the socket library to validate IP addresses, and this can trigger spurious DNS lookups when given an invalid IP address. ruby-ip does not depend on the socket library at all, unless you require 'ip/socket' to have access to the Socket::AF_INET and Socket::AF_INET6 constants.

Copying

You may use, distribute and modify this software under the same terms as ruby itself (see LICENSE.txt and COPYING.txt)