Class: NetAddr::CIDR

### Home Classes Methods

### In Files

- lib/cidr.rb

### Parent

Object

### Methods

- ::create
- ::new
- #<
- #<=>
- #==
- #>
- #[]
- #allocate_rfc3531
- #arpa
- #base
- #bits
- #cmp
- #contains?
- #desc
- #enumerate
- #eql?
- #fill_in
- #first
- #ip
- #is_contained?
- #last
- #matches?
- #multicast_mac
- #netmask
- #network
- #next_ip
- #next_subnet
- #nth
- #range
- #remainder
- #resize
- #resize!
- #set_wildcard_mask
- #size
- #subnet
- #succ
- #tag=
- #to_i
- #to_s
- #wildcard_mask

### Files

- Errors
- README
- changelog

### Class/Module Index

Quicksearch

- NetAddr
- NetAddr::CIDR
- NetAddr::CIDRv4
- NetAddr::CIDRv6
- NetAddr::EUI
- NetAddr::EUI48
- NetAddr::EUI64
- NetAddr::Tree

No matching classes.

# NetAddr::CIDR

# CIDR - Classless Inter-Domain Routing

A class & series of methods for creating and manipulating CIDR network addresses. Both IPv4 and IPv6 are supported.

This class accepts a CIDR address, via the CIDR.create method, in (x.x.x.x/yy or xxxx::/yy) format for IPv4 and IPv6, or (x.x.x.x/y.y.y.y) for IPv4. CIDR.create then creates either a CIDRv4 or CIDRv6 object. An optional tag hash may be provided with each CIDR as a way of adding custom labels.

Upon initialization, the IP version is auto-detected and assigned to the CIDR. The original IP/Netmask passed within the CIDR is stored and then used to determine the confines of the CIDR block. Various properties of the CIDR block are accessible via several different methods. There are also methods for modifying the CIDR or creating new derivative CIDR's.

An example CIDR object is as follows:

    NetAddr::CIDR.create('192.168.1.20/24')

This would create a CIDR object (192.168.1.0/24) with the following properties:

    version = 4
    base network = 192.168.1.0
    ip address = 192.168.1.20
    netmask = /24 (255.255.255.0)
    size = 256 IP addresses
    broadcast = 192.168.1.255

You can see how the CIDR object is based around the entire IP space defined by the provided IP/Netmask pair, and not necessarily the individual IP address itself.

### Attributes

address_len[R]

Integer representing number of bits in this CIDR address

all_f[R]

Integer of either 32 or 128 bits in length, with all bits set to 1

tag[R]

Hash of custom tags. Should be in the format tag => value.

version[R]

IP version 4 or 6.

### Public Class Methods

create(addr, options=nil) click to toggle source

### Synopsis

Create a new CIDRv4 or CIDRv6 object. CIDR formatted netmasks take precedence over extended formatted ones. CIDR address defaults to a host network (/32 or /128) if netmask not provided. :Mask takes precedence over netmask given within CIDR addresses. Version will be auto-detected if not specified.

    NetAddr::CIDR.create('192.168.1.1/24')
    NetAddr::CIDR.create('192.168.1.1 255.255.255.0')
    NetAddr::CIDR.create(0x0a010001,
                         :Mask => 0xffffff00
                         :Version => 4)
    NetAddr::CIDR.create('192.168.1.1',
                         :WildcardMask => ['0.7.0.255', true])
    NetAddr::CIDR.create('192.168.1.1',
                         :WildcardMask => [0x000007ff, true]
    NetAddr::CIDR.create('192.168.5.0',
                         :WildcardMask => ['255.248.255.0'])
    NetAddr::CIDR.create('fec0::/64')
    NetAddr::CIDR.create('fec0::/64',
                         :Tag => {'interface' => 'g0/1'})
    NetAddr::CIDR.create('::ffff:192.168.1.1/96')

### Arguments:

- addr = CIDR address as a String, or an IP address as an Integer

- options = Hash with the following keys:

      :Mask -- Integer representing a binary IP Netmask
      :Version -- IP version - Integer
      :Tag -- Custom descriptor tag - Hash, tag => value.
      :WildcardMask -- 2 element Array. First element contains a special bit mask used for
                       advanced IP pattern matching. The second element should be set to True if this
                       bit mask is bit flipped.

    # File lib/cidr.rb, line 110
    def CIDR.create(addr, options=nil)
        known_args = [:Mask, :Version, :Tag, :WildcardMask]
        ip, netmask, tag = nil, nil, {}
        version, wildcard_mask ,wildcard_mask_bit_flipped = nil, nil, false
        netmask_int, all_f = nil, nil

        # validate options
        if (options)
            raise ArgumentError, "Hash expected for argument 'options' but " +
                                 "#{options.class} provided." if (!options.kind_of?(Hash) )
            NetAddr.validate_args(options.keys,known_args)

            if (options.has_key?(:Mask))
                netmask_int = options[:Mask]
                raise ArgumentError, "Expected Integer, but #{netmask_int.class} " +
                                     "provided for option :Mask." if (!netmask_int.kind_of?(Integer))
            end

            if (options.has_key?(:Tag))
                tag = options[:Tag]
                if (!tag.kind_of? Hash)
                    raise ArgumentError, "Expected Hash, but #{tag.class} provided for option :Tag."
                end
            end

            if (options.has_key?(:Version))
                version = options[:Version]
                if (version != 4 && version != 6)
                    raise VersionError, ":Version should be 4 or 6, but was '#{version}'."
                end
            end

            if (options.has_key?(:WildcardMask))
                if (!options[:WildcardMask].kind_of?(Array))
                    raise ArgumentError, "Expected Array, but #{options[:WildcardMask].class} provided for option :WildcardMask."
                end

                wildcard_mask = options[:WildcardMask][0]
                if (!wildcard_mask.kind_of?(String) &&  !wildcard_mask.kind_of?(Integer))
                    raise ArgumentError, "Expected String or Integer, but #{wildcard_mask.class} provided for wildcard mask."
                end
                wildcard_mask_bit_flipped = true if (options[:WildcardMask][1] && options[:WildcardMask][1].kind_of?(TrueClass))
            end
        end

        # validate addr arg & set version if not provided by user
        if (addr.kind_of?(String))
            version = NetAddr.detect_ip_version(addr) if (!version)

            # if extended netmask provided. should only apply to ipv4
            if (version == 4 && addr =~ /.+\s+.+/ )
                addr,netmask = addr.split(' ')
            end

            # if netmask part of ip, then separate ip & mask.
            if (addr =~ /\//)
                ip,netmask = addr.split(/\//)
                if (!ip || !netmask)
                    raise ArgumentError, "CIDR address is improperly formatted. Missing netmask after '/' character."
                end
            else
                ip = addr
            end

            NetAddr.validate_ip_str(ip,version)
            ip = NetAddr.ip_str_to_int(ip,version)

        elsif (addr.kind_of?(Integer))
            ip = addr
            if (!version)
                if (ip < 2**32)
                    version = 4
                else
                    version = 6
                end
            end
            NetAddr.validate_ip_int(ip,version)

        else
            raise ArgumentError, "String or Integer expected for argument 'addr' but #{addr.class} provided."
        end

        # set all_f based on version
        all_f = 2**32-1
        all_f = 2**128-1 if (version == 6)

        # set netmask. netmask_int takes precedence. set to all_f if no netmask provided
        if (netmask_int)
            NetAddr.validate_netmask_int(netmask_int,version,true)
            netmask = netmask_int
        elsif (netmask)
            NetAddr.validate_netmask_str(netmask,version)
            netmask = NetAddr.netmask_str_to_int(netmask, version)
        else
            netmask = all_f
        end

        # set wildcard mask if not provided, or validate if provided.
        if (wildcard_mask)
            begin
                if (wildcard_mask.kind_of?(String))
                    NetAddr.validate_ip_str(wildcard_mask,version)
                    wildcard_mask = NetAddr.ip_str_to_int(wildcard_mask, version)
                else (wildcard_mask.kind_of?(Integer))
                    NetAddr.validate_ip_int(wildcard_mask,version)
                end
            rescue Exception => error
                raise ValidationError, "Provided wildcard mask failed validation: #{error}"
            end
        end

        return( NetAddr.cidr_build(version, ip, netmask, tag, wildcard_mask, wildcard_mask_bit_flipped) )
    end

new(ip, netmask=nil, tag={}, wildcard_mask=nil, wildcard_mask_bit_flipped=false) click to toggle source

    This method performs absolutely no error checking, and is meant to be used only by
    other internal methods for the sake of the speedier creation of CIDR objects.
    Please consider using #create unless you know what you are doing with 100% certainty.

### Arguments:

- ip - Integer representing an ip address

- netmask - Integer representing a binary netmask

- tag - Hash used to append custom tags to CIDR

- wildcard_mask - Integer representing a binary mask

- wildcard_mask_bit_flipped - indicates whether or not the wildcard_mask is bit-flipped or not

    # File lib/cidr.rb, line 239
    def initialize(ip, netmask=nil, tag={}, wildcard_mask=nil, wildcard_mask_bit_flipped=false)
        @ip = ip

        if ( self.kind_of?(NetAddr::CIDRv4) )
            @version = 4
            @address_len = 32
        else
            @version = 6
            @address_len = 128
        end
        @all_f = 2**@address_len - 1

        if (netmask)
            @netmask = netmask
        else
            @netmask = 2**@address_len - 1
        end

        @network = (@ip & @netmask)
        @hostmask = @netmask ^ @all_f
        @tag = tag

        if (!wildcard_mask)
            @wildcard_mask = @netmask
        else
            @wildcard_mask = wildcard_mask
            @wildcard_mask = ~@wildcard_mask if (wildcard_mask_bit_flipped)
        end

    end

### Public Instance Methods

<(cidr) click to toggle source

### Synopsis

Compare the sort order of the current CIDR with a provided CIDR and return true if current CIDR is less than provided CIDR.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.0/24')
    cidr < '192.168.2.0/24' => true

### Arguments:

- CIDR address or NetAddr::CIDR object

### Returns:

- true or false

    # File lib/cidr.rb, line 288
    def <(cidr)
        if (!cidr.kind_of?(NetAddr::CIDR))
            begin
                cidr = NetAddr::CIDR.create(cidr)
            rescue Exception => error
                raise ArgumentError, "Provided argument raised the following " +
                                     "errors: #{error}"
            end
        end

        if (cidr.version != @version)
            raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
                                 "with a version #{@version} CIDR."
        end

        # compare
        lt = false
        lt = true if ( NetAddr.cidr_gt_lt(self,cidr) == -1)

        return(lt)
    end

<=>(cidr) click to toggle source

### Synopsis

Compare the sort order of the current CIDR with a provided CIDR and return:

- 1 if the current CIDR is greater than the provided CIDR

- 0 if the current CIDR and the provided CIDR are equal (base address and netmask are equal)

- -1 if the current CIDR is less than the provided CIDR

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.0/24')
    cidr <=> '192.168.2.0/24' => -1
    cidr <=> '192.168.0.0/24' => 1
    cidr <=> '192.168.1.0/24' => 0

### Arguments:

- CIDR address or NetAddr::CIDR object

### Returns:

- Integer

    # File lib/cidr.rb, line 332
    def <=>(cidr)
        if (!cidr.kind_of?(NetAddr::CIDR))
            begin
                cidr = NetAddr::CIDR.create(cidr)
            rescue Exception => error
                raise ArgumentError, "Provided argument raised the following " +
                                     "errors: #{error}"
            end
        end

        if (cidr.version != @version)
            raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
                                 "with a version #{@version} CIDR."
        end

        # compare
        comparasin = NetAddr.cidr_gt_lt(self,cidr)

        return(comparasin)
    end

==(cidr) click to toggle source

### Synopsis

Compare the sort order of the current CIDR with a provided CIDR and return true if current CIDR is equal to the provided CIDR.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.0/24')
    cidr == '192.168.1.0/24' => true

### Arguments:

- CIDR address or NetAddr::CIDR object

### Returns:

- true or false

    # File lib/cidr.rb, line 371
    def ==(cidr)
        if (!cidr.kind_of?(NetAddr::CIDR))
            begin
                cidr = NetAddr::CIDR.create(cidr)
            rescue Exception => error
                raise ArgumentError, "Provided argument raised the following " +
                                     "errors: #{error}"
            end
        end

        if (cidr.version != @version)
            raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
                                 "with a version #{@version} CIDR."
        end

        # compare
        eq = false
        eq = true if ( NetAddr.cidr_gt_lt(self,cidr) == 0)

        return(eq)
    end

Also aliased as: eql?
>(cidr) click to toggle source

### Synopsis

Compare the sort order of the current CIDR with a provided CIDR and return true if current CIDR is greater than provided CIDR.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.0/24')
    cidr > '192.168.0.0/24' => true

### Arguments:

- CIDR address or NetAddr::CIDR object

### Returns:

- true or false

    # File lib/cidr.rb, line 412
    def >(cidr)
        if (!cidr.kind_of?(NetAddr::CIDR))
            begin
                cidr = NetAddr::CIDR.create(cidr)
            rescue Exception => error
                raise ArgumentError, "Provided argument raised the following " +
                                     "errors: #{error}"
            end
        end

        if (cidr.version != @version)
            raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
                                 "with a version #{@version} CIDR."
        end

        # compare
        gt = false
        gt = true if ( NetAddr.cidr_gt_lt(self,cidr) == 1)

        return(gt)
    end

[](index) click to toggle source

### Synopsis

Provide the IP at the given index of the CIDR.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
    cidr4[1] => 192.168.1.1/32

### Arguments:

- index = Index number as an Integer

### Returns:

- NetAddr::CIDR object.

    # File lib/cidr.rb, line 451
    def [](index)
        raise ArgumentError, "Integer expected for argument 'index' but " +
                             "#{index.class} provided." if (!index.kind_of?(Integer) )

        addr = @network + index
        if ( (@hostmask | addr) == (@hostmask | @network) )
            addr = NetAddr.cidr_build(@version, addr)
        else
            raise BoundaryError, "Index of #{index} returns IP that is out of " +
                                 "bounds of CIDR network."
        end

        return(addr)
    end

allocate_rfc3531(netmask, options=nil) click to toggle source

### Synopsis

RFC 3531 describes a flexible method for IP subnet allocation from a larger parent network. Given the new netmask for subnet allocations from this CIDR, provide a list of those subnets arranged by the order in which they should be allocated.

    Example:
    cidr = NetAddr::CIDR.create('192.168.0.0/16')
    cidr.allocate_rfc3531(21, :Strategy => :centermost) => ["192.168.0.0/21"... "192.168.248.0/21"]

### Arguments:

- netmask (in bits) for all new subnet allocations

- options = Hash with the following keys:

      :Objectify -- if true, return NetAddr::CIDR objects
      :Short -- if true, return IPv6 addresses in short-hand notation
      :Strategy -- allocation strategy to use. must be either :centermost or :leftmost (default)

### Returns:

- Array of Strings or CIDR objects

    # File lib/cidr.rb, line 489
    def allocate_rfc3531(netmask, options=nil)
        short = false
        objectify = false
        strategy = :leftmost

        # validate args
        raise ArgumentError, "Expected Integer for argument (netmask), but #{max.class} received." if ( !netmask.kind_of?(Integer) )
        raise BoundaryError, "Netmask (#{netmask}) is invalid for a version #{self.version} address." if (netmask > @address_len)
        raise BoundaryError, "Netmask (#{netmask}) cannot be less than #{self.bits}." if (netmask < self.bits)
        known_args = [:Objectify, :Short, :Strategy]
        if (options)
            if (!options.kind_of? Hash)
                raise ArgumentError, "Expected Hash, but #{options.class} provided."
            end
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Strategy))
                strategy = options[:Strategy]
                raise ArgumentError, "Argument :Strategy must be either :leftmost or :centermost." if (strategy != :leftmost && strategy != :centermost)
            end
        end

        subnet_bits = netmask - self.bits
        net_lshift = @address_len - netmask
        new_mask = NetAddr.bits_to_mask(netmask,self.version)
        cidr_list = []
        if (strategy == :leftmost)
            (0..(2**subnet_bits)-1).each do |num|
                mirror = NetAddr.binary_mirror(num, subnet_bits)

                if (!objectify)
                    my_ip_s = NetAddr.ip_int_to_str(@network | (mirror << net_lshift), @version)
                    my_ip_s = NetAddr.shorten(my_ip_s) if (short && @version == 6)
                    cidr_list.push( my_ip_s << '/' << netmask.to_s )
                else
                    cidr_list.push( NetAddr.cidr_build(@version, @network | (mirror << net_lshift), new_mask ) )
                end
            end

        else # :centermost
            round = 1
            bit_count = 1
            lshift = subnet_bits/2
            lshift -= 1 if (subnet_bits & 1 == 0) # if subnet_bits is even number

            unique = {}
            until (bit_count > subnet_bits)
                (0..2**bit_count-1).each do |num|
                    shifted = num << lshift
                    if ( !unique.has_key?(shifted) )
                        if (!objectify)
                            my_ip_s = NetAddr.ip_int_to_str(@network | (shifted << net_lshift), @version)
                            my_ip_s = NetAddr.shorten(my_ip_s) if (short && @version == 6)
                            cidr_list.push( my_ip_s << '/' << netmask.to_s )
                        else
                            cidr_list.push( NetAddr.cidr_build(@version, @network | (shifted << net_lshift), new_mask ) )
                        end
                        unique[shifted] = true
                    end
                end

                lshift -= 1 if (round & 1 == 0) # if even round
                round += 1
                bit_count += 1
            end
        end

        return(cidr_list)
    end

arpa() click to toggle source

### Synopsis

Depending on the IP version of the current CIDR, return either an in-addr.arpa. or ip6.arpa. string. The netmask will be used to determine the length of the returned string.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.1/24')
    cidr.arpa => "1.168.192.in-addr.arpa."

### Arguments:

- none

### Returns:

- String

    # File lib/cidr.rb, line 585
    def arpa()

        base = self.ip()
        netmask = self.bits()

        if (@version == 4)
            net = base.split('.')

            if (netmask)
                while (netmask < 32)
                    net.pop
                    netmask = netmask + 8
                end
            end

            arpa = net.reverse.join('.')
            arpa << ".in-addr.arpa."

        elsif (@version == 6)
            fields = base.split(':')
            net = []
            fields.each do |field|
                (field.split("")).each do |x|
                    net.push(x)
                end
            end

            if (netmask)
                while (netmask < 128)
                    net.pop
                    netmask = netmask + 4
                end
            end

            arpa = net.reverse.join('.')
            arpa << ".ip6.arpa."

        end

        return(arpa)
    end

base(options=nil) click to toggle source
Alias for: network
bits() click to toggle source

### Synopsis

Provide number of bits in Netmask.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.1/24')
    cidr.bits => 24

### Arguments:

- none

### Returns:

- Integer.

    # File lib/cidr.rb, line 643
    def bits()
        return(NetAddr.mask_to_bits(@netmask))
    end

cmp(cidr) click to toggle source

### Synopsis

Compare the current CIDR with a provided CIDR and return:

- 1 if the current CIDR contains (is supernet of) the provided CIDR

- 0 if the current CIDR and the provided CIDR are equal (base address and netmask are equal)

- -1 if the current CIDR is contained by (is subnet of) the provided CIDR

- nil if the two CIDR addresses are unrelated

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.0/24')
    cidr.cmp('192.168.1.0/25') => 1
    cidr.cmp('192.168.1.0/24') => 0
    cidr.cmp('192.168.0.0/23') => -1
    cidr.cmp('10.0.0.0/24') => nil

### Arguments:

- CIDR address or NetAddr::CIDR object

### Returns:

- Integer or nil

    # File lib/cidr.rb, line 671
        def cmp(cidr)
            if (!cidr.kind_of?(NetAddr::CIDR))
                begin
                    cidr = NetAddr::CIDR.create(cidr)
                rescue Exception => error
                    raise ArgumentError, "Provided argument raised the following " +
                                         "errors: #{error}"
                end
            end

            if (cidr.version != @version)
                raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
                                     "with a version #{@version} CIDR."
            end

            # compare
            comparasin = NetAddr.cidr_compare(self,cidr)

        return(comparasin)
    end

contains?(cidr) click to toggle source

### Synopsis

Determines if this CIDR contains (is supernet of) the provided CIDR address or NetAddr::CIDR object.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
    cidr6 = NetAddr::CIDR.create('fec0::/64')
    cidr6_2 = NetAddr::CIDR.create('fec0::/96')
    cidr4.contains?('192.168.1.2') => true
    cidr6.contains?(cidr6_2) => true

### Arguments:

- cidr = CIDR address or NetAddr::CIDR object

### Returns:

- true or false

    # File lib/cidr.rb, line 713
    def contains?(cidr)
        contains = false

        if (!cidr.kind_of?(NetAddr::CIDR))
            begin
                cidr = NetAddr::CIDR.create(cidr)
            rescue Exception => error
                raise ArgumentError, "Provided argument raised the following " +
                                     "errors: #{error}"
            end
        end

        if (cidr.version != @version)
            raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
                                 "with a version #{@version} CIDR."
        end

        contains = true if ( NetAddr.cidr_compare(self,cidr) == 1 )

        return(contains)
    end

desc(options=nil) click to toggle source

### Synopsis

See to_s

    # File lib/cidr.rb, line 742
    def desc(options=nil)
        to_s(options)
    end

enumerate(options=nil) click to toggle source

### Synopsis

Provide all IP addresses contained within the IP space of this CIDR.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
    cidr6 = NetAddr::CIDR.create('fec0::/64')
    cidr4.enumerate(:Limit => 4, :Bitstep => 32)
    cidr6.enumerate(:Limit => 4, :Bitstep => 32, :Objectify => true)

### Arguments:

- options = Hash with the following keys:

      :Bitstep -- enumerate in X sized steps - Integer
      :Limit -- limit returned list to X number of items - Integer
      :Objectify -- if true, return NetAddr::CIDR objects
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- Array of Strings, or Array of NetAddr::CIDR objects

    # File lib/cidr.rb, line 769
    def enumerate(options=nil)
        known_args = [:Bitstep, :Limit, :Objectify, :Short]
        bitstep = 1
        objectify = false
        limit = nil
        short = false

        if (options)
            if (!options.kind_of? Hash)
                raise ArgumentError, "Expected Hash, but #{options.class} provided."
            end
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Bitstep) )
                bitstep = options[:Bitstep]
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end

            if( options.has_key?(:Limit) )
                limit = options[:Limit]
            end

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end
        end

        list = []
        my_ip = @network
        change_mask = @hostmask | my_ip

        until ( change_mask != (@hostmask | @network) )
            if (!objectify)
                my_ip_s = NetAddr.ip_int_to_str(my_ip, @version)
                my_ip_s = NetAddr.shorten(my_ip_s) if (short && @version == 6)
                list.push( my_ip_s )
            else
                list.push( NetAddr.cidr_build(@version,my_ip) )
            end
            my_ip = my_ip + bitstep
            change_mask = @hostmask | my_ip
            if (limit)
                limit = limit -1
                break if (limit == 0)
            end
        end

        return(list)
    end

eql?(cidr) click to toggle source
Alias for: ==
fill_in(list, options=nil) click to toggle source

### Synopsis

Given a list of subnets of the current CIDR, return a new list with any holes (missing subnets) filled in.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
    cidr4.fill_in(['192.168.1.0/27','192.168.1.64/26','192.168.1.128/25'])

### Arguments:

- list = Array of CIDR addresses, or Array of NetAddr::CIDR objects

- options = Hash with the following keys:

      :Objectify -- if true, return NetAddr::CIDR objects
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- Array of CIDR Strings, or an Array of NetAddr::CIDR objects

    # File lib/cidr.rb, line 844
    def fill_in(list, options=nil)
        known_args = [:Objectify, :Short]
        short = false
        objectify = false

        # validate list
        raise ArgumentError, "Array expected for argument 'list' but #{list.class} provided." if (!list.kind_of?(Array) )

        # validate options
        if (options)
            raise ArgumentError, "Hash expected for argument 'options' but " +
                                 "#{options.class} provided." if (!options.kind_of?(Hash) )
            NetAddr.validate_args(options.keys,known_args)

            if (options.has_key?(:Short) && options[:Short] == true)
                short = true
            end

            if (options.has_key?(:Objectify) && options[:Objectify] == true)
                objectify = true
            end
        end

        # validate each cidr and store in cidr_list
        cidr_list = []
        list.each do |obj|
            if (!obj.kind_of?(NetAddr::CIDR))
                begin
                    obj = NetAddr::CIDR.create(obj)
                rescue Exception => error
                    aise ArgumentError, "A provided CIDR raised the following " +
                                        "errors: #{error}"
                end
            end

            if (!obj.version == self.version)
                raise VersionError, "#{obj.desc(:Short => true)} is not a version #{self.version} address."
            end

            # make sure we contain the cidr
            if ( self.contains?(obj) == false )
                raise "#{obj.desc(:Short => true)} does not fit " +
                      "within the bounds of #{self.desc(:Short => true)}."
            end
            cidr_list.push(obj)
        end

        complete_list = NetAddr.cidr_fill_in(self,cidr_list)
        if (!objectify)
            subnets = []
            complete_list.each {|entry| subnets.push(entry.desc(:Short => short))}
            return(subnets)
        else
            return(complete_list)
        end
    end

first(options=nil) click to toggle source
Alias for: network
ip(options=nil) click to toggle source

### Synopsis

Provide original IP address passed during initialization.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.1/24')
    cidr.ip => "192.168.1.1"

### Arguments:

- options = Hash with the following keys:

      :Objectify -- if true, return NetAddr::CIDR object
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- String or NetAddr::CIDR object.

    # File lib/cidr.rb, line 920
    def ip(options=nil)
        known_args = [:Objectify, :Short]
        objectify = false
        short = false

        if (options)
            if (!options.kind_of?(Hash))
                raise Argumenterror, "Expected Hash, but " +
                                     "#{options.class} provided."
            end
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end
        end

        if (!objectify)
            ip = NetAddr.ip_int_to_str(@ip, @version)
            ip = NetAddr.shorten(ip) if (short && @version == 6)
        else
            ip = NetAddr.cidr_build(@version,@ip)
        end

        return(ip)
    end

is_contained?(cidr) click to toggle source

### Synopsis

Determines if this CIDR is contained within (is subnet of) the provided CIDR address or NetAddr::CIDR object.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
    cidr4.is_contained?('192.168.0.0/23')

### Arguments:

- cidr = CIDR address or NetAddr::CIDR object

### Returns:

- true or false

    # File lib/cidr.rb, line 970
    def is_contained?(cidr)
        is_contained = false

        if (!cidr.kind_of?(NetAddr::CIDR))
            begin
                cidr = NetAddr::CIDR.create(cidr)
            rescue Exception => error
                raise ArgumentError, "Provided argument raised the following " +
                                     "errors: #{error}"
            end
        end

        if (cidr.version != @version)
            raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
                                 "with a version #{@version} CIDR."
        end

        network = cidr.to_i(:network)
        netmask = cidr.to_i(:netmask)
        hostmask = cidr.to_i(:hostmask)

        is_contained = true if ( NetAddr.cidr_compare(self,cidr) == -1 )

        return(is_contained)
    end

last(options=nil) click to toggle source

### Synopsis

Provide last IP address in this CIDR object.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.0/24')
    cidr.last => "192.168.1.255"

### Arguments:

- options = Hash with the following keys:

      :Objectify -- if true, return NetAddr::CIDR object
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- String or NetAddr::CIDR object.

    # File lib/cidr.rb, line 1015
    def last(options=nil)
        known_args = [:Objectify, :Short]
        objectify = false
        short = false

        if (options)
            if (!options.kind_of?(Hash))
                raise Argumenterror, "Expected Hash, but " +
                                     "#{options.class} provided."
            end
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end

        end

        ip_int = @network | @hostmask
        if (!objectify)
            ip = NetAddr.ip_int_to_str(ip_int, @version)
            ip = NetAddr.shorten(ip) if (short && !objectify && @version == 6)
        else
            ip = NetAddr.cidr_build(@version,ip_int)
        end

        return(ip)
    end

matches?(ip) click to toggle source

### Synopsis

Given an IP address (or if a NetAddr::CIDR object, then the original IP of that object), determine if it falls within the range of addresses resulting from the combination of the IP and Wildcard Mask of this CIDR.

    Example:
    cidr4 = NetAddr.CIDRv4.create('10.0.0.0', :WildcardMask => ['0.7.0.255', true])
    cidr4.matches?('10.0.0.22') -> true
    cidr4.matches?('10.8.0.1') -> false
    cidr4.matches?('10.1.0.1') -> true
    cidr4.matches?('10.0.1.22') -> false

### Arguments:

- ip = IP address as a String or a CIDR object

### Returns:

- True or False

    # File lib/cidr.rb, line 1070
    def matches?(ip)
        ip_int = nil
        if (!ip.kind_of?(NetAddr::CIDR))
            begin
                ip_int = NetAddr.ip_to_i(ip, :Version => @version)
            rescue NetAddr::ValidationError
                raise NetAddr::ValidationError, "Provided IP must be a valid IPv#{@version} address."
            end
        else
            raise NetAddr::ValidationError, "Provided CIDR must be of type #{self.class}" if (ip.class != self.class)
            ip_int = ip.to_i(:ip)
        end

        return(true) if (@ip & @wildcard_mask == ip_int & @wildcard_mask)
        return(false)
    end

multicast_mac(options=nil) click to toggle source

### Synopsis

Assuming this CIDR is a valid multicast address (224.0.0.0/4 for IPv4 and ff00::/8 for IPv6), return its ethernet MAC address (EUI-48) mapping. MAC address is based on original IP address passed during initialization.

    Example:
    mcast = NetAddr::CIDR.create('224.0.0.6')
    mcast.multicast_mac.address

### Arguments:

- options = Hash with the following keys:

      :Objectify -- if true, return EUI objects

### Returns:

- String or NetAddr::EUI48 object

    # File lib/cidr.rb, line 1107
    def multicast_mac(options=nil)
        known_args = [:Objectify]
        objectify = false

        if (options)
            if (!options.kind_of? Hash)
                raise ArgumentError, "Expected Hash, but #{options.class} provided."
            end
            NetAddr.validate_args(options.keys,known_args)

            if (options.has_key?(:Objectify) && options[:Objectify] == true)
                objectify = true
            end
        end

        if (@version == 4)
            if (@ip & 0xf0000000 == 0xe0000000)
                # map low order 23-bits of ip to 01:00:5e:00:00:00
                mac = @ip & 0x007fffff | 0x01005e000000
            else
                raise ValidationError, "#{self.ip} is not a valid multicast address. IPv4 multicast " +
                      "addresses should be in the range 224.0.0.0/4."
            end
        else
            if (@ip & (0xff << 120) == 0xff << 120)
                # map low order 32-bits of ip to 33:33:00:00:00:00
                mac = @ip & (2**32-1) | 0x333300000000
            else
                raise ValidationError, "#{self.ip} is not a valid multicast address. IPv6 multicast " +
                      "addresses should be in the range ff00::/8."
            end
        end

        eui = NetAddr::EUI48.new(mac)
        eui = eui.address if (!objectify)

        return(eui)
    end

netmask() click to toggle source

### Synopsis

Provide netmask in CIDR format (/yy).

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.0/24')
    cidr.netmask => "/24"

### Arguments:

- none

### Returns:

- String

    # File lib/cidr.rb, line 1163
    def netmask()
        bits = NetAddr.mask_to_bits(@netmask)
        return("/#{bits}")
    end

network(options=nil) click to toggle source

### Synopsis

Provide base network address.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.0/24')
    cidr.network => "192.168.1.0"

### Arguments:

- options = Hash with the following fields:

      :Objectify -- if true, return NetAddr::CIDR object
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- String or NetAddr::CIDR object.

    # File lib/cidr.rb, line 1187
    def network(options=nil)
        known_args = [:Objectify, :Short]
        objectify = false
        short = false

        if (options)
            if (!options.kind_of?(Hash))
                raise Argumenterror, "Expected Hash, but " +
                                     "#{options.class} provided."
            end
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end
        end

        if (!objectify)
            ip = NetAddr.ip_int_to_str(@network, @version)
            ip = NetAddr.shorten(ip) if (short && @version == 6)
        else
            ip = NetAddr.cidr_build(@version,@network)
        end

        return(ip)
    end

Also aliased as: base, first
next_ip(options=nil) click to toggle source

### Synopsis

Provide the next IP following the last available IP within this CIDR object.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
    cidr6 = NetAddr::CIDR.create('fec0::/64')
    cidr4.next_subnet()
    cidr6.next_subnet(:Short => true)}

### Arguments:

- options = Hash with the following keys:

      :Bitstep -- step in X sized steps - Integer
      :Objectify -- if true, return NetAddr::CIDR object
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- String or NetAddr::CIDR object.

    # File lib/cidr.rb, line 1244
    def next_ip(options=nil)
        known_args = [:Bitstep, :Objectify, :Short]
        bitstep = 1
        objectify = false
        short = false

        if (options)
            if (!options.kind_of?(Hash))
                raise Argumenterror, "Expected Hash, but " +
                                     "#{options.class} provided."
            end
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Bitstep) )
                bitstep = options[:Bitstep]
            end

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end
        end

        next_ip = @network + @hostmask + bitstep

        if (next_ip > @all_f)
            raise BoundaryError, "Returned IP is out of bounds for IPv#{@version}."
        end

        if (!objectify)
            next_ip = NetAddr.ip_int_to_str(next_ip, @version)
            next_ip = NetAddr.shorten(next_ip) if (short && @version == 6)
        else
            next_ip = NetAddr.cidr_build(@version,next_ip)
        end

        return(next_ip)
    end

next_subnet(options=nil) click to toggle source

### Synopsis

Provide the next subnet following this CIDR object. The next subnet will be of the same size as the current CIDR object.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
    cidr6 = NetAddr::CIDR.create('fec0::/64')
    cidr4.next_subnet()
    cidr6.next_subnet(:Short => true)

### Arguments:

- options = Hash with the following keys:

      :Bitstep -- step in X sized steps. - Integer
      :Objectify -- if true, return NetAddr::CIDR object
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- String or NetAddr::CIDR object.

    # File lib/cidr.rb, line 1310
    def next_subnet(options=nil)
        known_args = [:Bitstep, :Objectify, :Short]
        bitstep = 1
        objectify = false
        short = false

        if (options)
            if (!options.kind_of?(Hash))
                raise Argumenterror, "Expected Hash, but " +
                                     "#{options.class} provided."
            end
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Bitstep) )
                bitstep = options[:Bitstep]
            end

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end
        end

        bitstep = bitstep * (2**(@address_len - self.bits) )
        next_sub = @network + bitstep

        if (next_sub > @all_f)
            raise BoundaryError, "Returned subnet is out of bounds for IPv#{@version}."
        end

        if (!objectify)
            next_sub = NetAddr.ip_int_to_str(next_sub, @version)
            next_sub = NetAddr.shorten(next_sub) if (short && @version == 6)
            next_sub = next_sub << "/" << self.bits.to_s
        else
            next_sub = NetAddr.cidr_build(@version,next_sub,self.to_i(:netmask))
        end

        return(next_sub)
    end

nth(index, options=nil) click to toggle source

### Synopsis

Provide the nth IP within this object.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
    cidr4.nth(1)
    cidr4.nth(1, :Objectify => true)

### Arguments:

- index = Index number as an Integer

- options = Hash with the following keys:

      :Objectify -- if true, return NetAddr::CIDR objects
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- String or NetAddr::CIDR object.

    # File lib/cidr.rb, line 1375
    def nth(index, options=nil)
        known_args = [:Objectify, :Short]
        objectify = false
        short = false

        # validate list
        raise ArgumentError, "Integer expected for argument 'index' but " +
                             "#{index.class} provided." if (!index.kind_of?(Integer) )

        # validate options
        if (options)
            raise ArgumentError, "Hash expected for argument 'options' but #{options.class} provided." if (!options.kind_of?(Hash) )
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                    objectify = true
            end
        end

        my_ip = @network + index
        if ( (@hostmask | my_ip) == (@hostmask | @network) )

            if (!objectify)
                my_ip = NetAddr.ip_int_to_str(my_ip, @version)
                my_ip = NetAddr.shorten(my_ip) if (short && @version == 6)
            else
                my_ip = NetAddr.cidr_build(@version,my_ip)
             end

        else
            raise BoundaryError, "Index of #{index} returns IP that is out of " +
                                 "bounds of CIDR network."
        end

        return(my_ip)
    end

range(lower, upper=nil, options=nil) click to toggle source

### Synopsis

Given a set of index numbers for this CIDR, return all IP addresses within the CIDR that are between them (inclusive). If an upper bound is not provided, then all addresses from the lower bound up will be returned.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
    cidr4.range(0, 1)
    cidr4.range(0, 1, :Objectify => true)
    cidr4.range(0, nil, :Objectify => true)

### Arguments:

- lower = Lower range boundary index as an Integer

- upper = Upper range boundary index as an Integer

- options = Hash with the following keys:

      :Bitstep -- enumerate in X sized steps - Integer
      :Objectify -- if true, return NetAddr::CIDR objects
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- Array of Strings, or Array of NetAddr::CIDR objects

### Note:

If you do not need all of the fancy options in this method, then please consider using the standard Ruby Range class as shown below.

    Example:
    start = NetAddr::CIDR.create('192.168.1.0')
    fin = NetAddr::CIDR.create('192.168.2.3')
    (start..fin).each {|addr| puts addr.desc}

    # File lib/cidr.rb, line 1451
    def range(lower, upper=nil, options=nil)
        known_args = [:Bitstep, :Objectify, :Short]
        objectify = false
        short = false
        bitstep = 1

        # validate indexes
        raise ArgumentError, "Integer expected for argument 'lower' " +
                             "but #{lower.class} provided." if (!lower.kind_of?(Integer))

        raise ArgumentError, "Integer expected for argument 'upper' " +
                             "but #{upper.class} provided." if (upper && !upper.kind_of?(Integer))

        upper = @hostmask if (upper.nil?)
        indexes = [lower,upper]
        indexes.sort!
        if ( (indexes[0] < 0) || (indexes[0] > self.size) )
            raise BoundaryError, "Index #{indexes[0]} is out of bounds for this CIDR."
        end

        if (indexes[1] >= self.size)
            raise BoundaryError, "Index #{indexes[1]} is out of bounds for this CIDR."
        end

        # validate options
        if (options)
            raise ArgumentError, "Hash expected for argument 'options' but #{options.class} provided." if (!options.kind_of?(Hash) )
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end

            if( options.has_key?(:Bitstep) )
                bitstep = options[:Bitstep]
            end
        end

        # make range
        start_ip = @network + indexes[0]
        end_ip = @network + indexes[1]
        my_ip = start_ip
        list = []
        until (my_ip > end_ip)
            if (!objectify)
                ip = NetAddr.ip_int_to_str(my_ip, @version)
                ip = NetAddr.shorten(ip) if (short && @version == 6)
            else
                ip = NetAddr.cidr_build(@version,my_ip)
            end

            list.push(ip)
            my_ip += bitstep
        end

        return(list)
    end

remainder(addr, options=nil) click to toggle source

### Synopsis

Given a single subnet of the current CIDR, provide the remainder of the subnets. For example if the original CIDR is 192.168.0.0/24 and you provide 192.168.0.64/26 as the portion to exclude, then 192.168.0.0/26, and 192.168.0.128/25 will be returned as the remainders.

    cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
    cidr4.remainder('192.168.1.32/27')
    cidr4.remainder('192.168.1.32/27', :Objectify => true)

### Arguments:

- addr = CIDR address or NetAddr::CIDR object

- options = Hash with the following keys:

      :Objectify -- if true, return NetAddr::CIDR objects
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- Array of Strings, or Array of NetAddr::CIDR objects

    # File lib/cidr.rb, line 1536
    def remainder(addr, options=nil)
        known_args = [:Objectify, :Short]
        short = nil
        objectify = nil

        # validate options
        if (options)
            raise ArgumentError, "Hash expected for argument 'options' but " +
                                 "#{options.class} provided." if (!options.kind_of?(Hash) )
            NetAddr.validate_args(options.keys,known_args)

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end
        end

        if ( !addr.kind_of?(NetAddr::CIDR) )
            begin
                addr = NetAddr::CIDR.create(addr)
            rescue Exception => error
                raise ArgumentError, "Argument 'addr' raised the following " +
                                     "errors: #{error}"
            end
        end

        # make sure 'addr' is the same ip version
        if ( addr.version != @version )
            raise VersionError, "#{addr.desc(:Short => true)} is of a different " +
                                "IP version than #{self.desc(:Short => true)}."
        end

        # make sure we contain 'to_exclude'
        if ( self.contains?(addr) != true )
            raise BoundaryError, "#{addr.desc(:Short => true)} does not fit " +
                                 "within the bounds of #{self.desc(:Short => true)}."
        end

        # split this cidr in half & see which half 'to_exclude'
        # belongs in. take that half & repeat the process. every time
        # we repeat, store the non-matching half
        new_mask = self.bits + 1
        lower_network = self.to_i(:network)
        upper_network = self.to_i(:network) + 2**(@address_len - new_mask)

        new_subnets = []
        until(new_mask > addr.bits)
            if (addr.to_i(:network) < upper_network)
                match = lower_network
                non_match = upper_network
            else
                match = upper_network
                non_match = lower_network
            end

            if (!objectify)
                non_match = NetAddr.ip_int_to_str(non_match, @version)
                non_match = NetAddr.shorten(non_match) if (short && @version == 6)
                new_subnets.unshift("#{non_match}/#{new_mask}")
            else
                new_subnets.unshift( NetAddr.cidr_build(@version, non_match, NetAddr.bits_to_mask(new_mask,version) ) )
            end

            new_mask = new_mask + 1
            lower_network = match
            upper_network = match + 2**(@address_len - new_mask)
        end

        return(new_subnets)
    end

resize(bits) click to toggle source

### Synopsis

Resize the CIDR by changing the size of the Netmask. Return the resulting CIDR as a new object.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
    new_cidr = cidr4.resize(23)

### Arguments:

- bits = Netmask as an Integer

### Returns:

- NetAddr::CIDR object

    # File lib/cidr.rb, line 1629
    def resize(bits)
        raise Argumenterror, "Integer or Hash expected, but " +
                             "#{bits.class} provided." if (!bits.kind_of?(Integer))

        NetAddr.validate_ip_netmask(bits, :Version => @version)
        netmask = NetAddr.bits_to_mask(bits, @version)
        network = @network & netmask

        return( NetAddr.cidr_build(@version, network, netmask) )
    end

resize!(bits) click to toggle source

### Synopsis

Resize the current CIDR by changing the size of the Netmask. The original IP passed during initialization will be set to the base network address if it no longer falls within the bounds of the CIDR.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
    cidr4.resize!(23)

### Arguments:

- bits = Netmask as an Integer

### Returns:

- True

    # File lib/cidr.rb, line 1659
    def resize!(bits)
        raise Argumenterror, "Integer or Hash expected, but " +
                                 "#{bits.class} provided." if (!bits.kind_of?(Integer))

        NetAddr.validate_ip_netmask(bits, :Version => @version)
        netmask = NetAddr.netmask_to_i(bits, :Version => @version)

        @netmask = netmask
        @network = @network & netmask
        @hostmask = @netmask ^ @all_f

        # check @ip
        if ((@ip & @netmask) != (@network))
            @ip = @network
        end

        return(true)
    end

set_wildcard_mask(mask, bit_flipped=false) click to toggle source

### Synopsis

Set the wildcard mask. Wildcard masks are typically used for matching entries in an access-list.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
    cidr4.set_wildcard_mask('0.0.0.255', true)
    cidr4.set_wildcard_mask('255.255.255.0')

### Arguments:

- mask = wildcard mask as a String or Integer

- bit_flipped = if set True then the wildcard mask is interpereted as bit-flipped.

### Returns:

- nil

    # File lib/cidr.rb, line 1698
    def set_wildcard_mask(mask, bit_flipped=false)
        netmask_int = nil
        if (mask.kind_of?(Integer))
            NetAddr.validate_ip_int(mask,@version)
            netmask_int = mask
        else
            begin
                NetAddr.validate_ip_str(mask,@version)
                netmask_int = NetAddr.ip_str_to_int(mask, @version)
            rescue NetAddr::ValidationError
                raise NetAddr::ValidationError, "Wildcard Mask must be a valid IPv#{@version} address."
            end
        end
        netmask_int = ~netmask_int if (bit_flipped)
        @wildcard_mask = netmask_int

        return(nil)
    end

size() click to toggle source

### Synopsis

Provide number of IP addresses within this CIDR.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.0/24')
    cidr.size => 256

### Arguments:

- none

### Returns:

- Integer

    # File lib/cidr.rb, line 1734
    def size()
        return(@hostmask + 1)
    end

subnet(options=nil) click to toggle source

### Synopsis

Create subnets for this CIDR. There are 2 ways to create subnets:

    * By providing the netmask (in bits) of the new subnets with :Bits.
    * By providing the number of IP addresses needed in the new subnets with :IPCount

:NumSubnets is used to determine how the CIDR is subnetted. For example, if I request the following operation:

    NetAddr::CIDR.create('192.168.1.0/24').subnet(:Bits => 26, :NumSubnets => 1)

then I would get back the first /26 subnet of 192.168.1.0/24 and the remainder of the IP space as summary CIDR addresses (e.g. 192.168.1.0/26, 192.168.1.64/26, and 192.168.1.128/25). If I were to perform the same operation without the :NumSubnets directive, then 192.168.1.0/24 will be fully subnetted into X number of /26 subnets (e.g. 192.168.1.0/26, 192.168.1.64/26, 192.168.1.128/26, and 192.168.1.192/26).

If neither :Bits nor :IPCount is provided, then the current CIDR will be split in half. If both :Bits and :IPCount are provided, then :Bits takes precedence.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
    cidr6 = NetAddr::CIDR.create('fec0::/64')
    cidr4.subnet(:Bits => 28, :NumSubnets => 3)
    cidr4.subnet(:IPCount => 19)
    cidr4.subnet(:Bits => 28)
    cidr6.subnet(:Bits => 67, :NumSubnets => 4, :Short => true)

### Arguments:

- options = Hash with the following keys:

      :Bits --  Netmask (in bits) of new subnets - Integer
      :IPCount -- Minimum number of IP's that new subnets should contain - Integer
      :NumSubnets -- Number of X sized subnets to return - Integer
      :Objectify -- if true, return NetAddr::CIDR objects
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- Array of Strings, or Array of NetAddr::CIDR objects

    # File lib/cidr.rb, line 1780
    def subnet(options=nil)
        known_args = [:Bits, :IPCount, :NumSubnets, :Objectify, :Short]
        my_network = self.to_i(:network)
        my_mask = self.bits
        subnet_bits = my_mask + 1
        min_count = nil
        objectify = false
        short = false

        if (options)
            if (!options.kind_of? Hash)
                raise ArgumentError, "Expected Hash, but #{options.class} provided."
            end
            NetAddr.validate_args(options.keys,known_args)

            if ( options.has_key?(:IPCount) )
                subnet_bits = NetAddr.ip_count_to_size(options[:IPCount], @version)
            end

            if ( options.has_key?(:Bits) )
                subnet_bits = options[:Bits]
            end

            if ( options.has_key?(:NumSubnets) )
                num_subnets = options[:NumSubnets]
            end

            if( options.has_key?(:Short) && options[:Short] == true )
                short = true
            end

            if( options.has_key?(:Objectify) && options[:Objectify] == true )
                objectify = true
            end

        end

        # get number of subnets possible with the requested subnet_bits
        num_avail = 2**(subnet_bits - my_mask)

        # get the number of bits in the next supernet and
        # make sure num_subnets is a power of 2
        bits_needed = 1
        num_subnets = num_avail if (!num_subnets)
        until (2**bits_needed >= num_subnets)
            bits_needed += 1
        end
        num_subnets = 2**bits_needed
        next_supernet_bits = subnet_bits - bits_needed

        # make sure subnet isnt bigger than available bits
        if (subnet_bits > @address_len)
            raise BoundaryError, "Requested subnet (#{subnet_bits}) does not fit " +
                  "within the bounds of IPv#{@version}."
        end

        # make sure subnet is larger than mymask
        if (subnet_bits < my_mask)
            raise BoundaryError, "Requested subnet (#{subnet_bits}) is too large for " +
                  "current CIDR space."
        end

        # make sure MinCount is smaller than available subnets
        if (num_subnets > num_avail)
            raise "Requested subnet count (#{num_subnets}) exceeds subnets " +
                  "available for allocation (#{num_avail})."
        end

        # list all 'subnet_bits' sized subnets of this cidr block
        # with a limit of num_subnets
        bitstep = 2**(@address_len - subnet_bits)
        subnets = self.enumerate(:Bitstep => bitstep, :Limit => num_subnets, :Objectify => true)

        # save our subnets
        new_subnets = []
        subnets.each do |subnet|
            if (!objectify)
                if (short && @version == 6)
                    new_subnets.push("#{subnet.network(:Short => true)}/#{subnet_bits}")
                else
                    new_subnets.push("#{subnet.network}/#{subnet_bits}")
                end
            else
                new_subnets.push( NetAddr.cidr_build(@version, subnet.to_i(:network), NetAddr.bits_to_mask(subnet_bits,version) ) )
            end
        end

        # now go through the rest of the cidr space and make the rest
        # of the subnets. we want these to be as tightly merged as possible
        next_supernet_bitstep = (bitstep * num_subnets)
        next_supernet_ip = my_network + next_supernet_bitstep
        until (next_supernet_bits == my_mask)
            if (!objectify)
                next_network = NetAddr.ip_int_to_str(next_supernet_ip, @version)
                next_network = NetAddr.shorten(next_network) if (short && @version == 6)
                new_subnets.push("#{next_network}/#{next_supernet_bits}")
            else
                new_subnets.push(NetAddr.cidr_build(@version, next_supernet_ip, NetAddr.bits_to_mask(next_supernet_bits,version) ) )
            end

            next_supernet_bits -= 1
            next_supernet_ip = next_supernet_ip + next_supernet_bitstep
            next_supernet_bitstep = next_supernet_bitstep << 1
        end

        return(new_subnets)
    end

succ() click to toggle source

### Synopsis

Provide the next subnet following this CIDR object. The next subnet will be of the same size as the current CIDR object.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.0/24')
    cidr.succ => 192.168.2.0/24

### Arguments:

- none

### Returns:

- NetAddr::CIDR object.

    # File lib/cidr.rb, line 1907
    def succ()
        bitstep = 2**(@address_len - self.bits)
        next_sub = @network + bitstep

        if (next_sub > @all_f)
            raise BoundaryError, "Returned subnet is out of bounds for IPv#{@version}."
        end

        next_sub = NetAddr.cidr_build(@version,next_sub,self.to_i(:netmask))

        return(next_sub)
    end

tag=(new_tag) click to toggle source

Hash of custom tags. Should be in the format tag => value.

Example:

    cidr4.tag[:name] = 'IPv4 CIDR'
    puts cidr4.tag[:name]

    # File lib/cidr.rb, line 66
    def tag=(new_tag)
        if (!new_tag.kind_of? Hash)
            raise ArgumentError, "Expected Hash, but #{new_tag.class} provided."
        end
        @tag = new_tag
    end

to_i(attribute=:network) click to toggle source

### Synopsis

Convert the requested attribute of the CIDR to an Integer.

    Example:
    cidr = NetAddr::CIDR.create('192.168.1.1/24')
    cidr.to_i => 3232235776
    cidr.to_i(:hostmask) => 255
    cidr.to_i(:ip) => 3232235777
    cidr.to_i(:netmask) => 4294967040
    cidr.to_i(:wildcard_mask) => 4294967040

### Arguments:

- attribute -- attribute of the CIDR to convert to an Integer (:hostmask, :ip, :netmask, :network, or :wildcard_mask).

### Returns:

- Integer

    # File lib/cidr.rb, line 1940
    def to_i(attribute=:network)
        if(attribute == :network)
            return(@network)
        elsif(attribute == :hostmask)
            return(@hostmask)
        elsif(attribute == :ip)
            return(@ip)
        elsif(attribute == :netmask)
            return(@netmask)
        elsif(attribute == :wildcard_mask)
            return(@wildcard_mask)
        else
            raise ArgumentError, "Attribute is unrecognized. Must be :hostmask, :ip, :netmask, :network, or :wildcard_mask."
        end
    end

to_s(options=nil) click to toggle source

### Synopsis

Returns network/netmask in CIDR format.

    Example:
    cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
    cidr6 = NetAddr::CIDR.create('fec0::/64')
    cidr4.desc(:IP => true) => "192.168.1.1/24"
    cidr4.to_s => "192.168.1.0/24"
    cidr6.to_s(:Short => true) => "fec0::/64"

### Arguments:

- options = Optional hash with the following keys:

      :IP -- if true, return the original ip/netmask passed during initialization
      :Short -- if true, return IPv6 addresses in short-hand notation

### Returns:

- String

    # File lib/cidr.rb, line 1978
    def to_s(options=nil)
        known_args = [:IP, :Short]
        short = false
        orig_ip = false

        if (options)
            if (!options.kind_of? Hash)
                raise ArgumentError, "Expected Hash, but #{options.class} provided."
            end
            NetAddr.validate_args(options.keys,known_args)

            if (options.has_key?(:Short) && options[:Short] == true)
                short = true
            end

            if (options.has_key?(:IP) && options[:IP] == true)
                orig_ip = true
            end
        end

        if (!orig_ip)
            ip = NetAddr.ip_int_to_str(@network, @version)
        else
            ip = NetAddr.ip_int_to_str(@ip, @version)
        end
        ip = NetAddr.shorten(ip) if (short && @version == 6)
        mask = NetAddr.mask_to_bits(@netmask)

        return("#{ip}/#{mask}")
    end

wildcard_mask(bit_flipped=false) click to toggle source

### Synopsis

Return the wildcard mask.

    Example:
    cidr = NetAddr::CIDR.create('10.1.0.0/24', :WildcardMask => ['0.7.0.255', true])
    cidr.wildcard_mask => "255.248.255.0"
    cidr.wildcard_mask(true) => "0.7.0.255"

### Arguments:

- bit_flipped = if set True then returned the bit-flipped version of the wildcard mask.

### Returns:

- String

    # File lib/cidr.rb, line 2027
    def wildcard_mask(bit_flipped=false)
        ret_val = nil
        if (!bit_flipped)
            ret_val = NetAddr.ip_int_to_str(@wildcard_mask, @version)
        else
            ret_val = NetAddr.ip_int_to_str(~@wildcard_mask, @version)
        end

        return(ret_val)
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.