Problem with IPAddr

Discussion in 'Ruby' started by Bryan Richardson, Jan 16, 2008.

  1. [Note: parts of this message were removed to make it a legal post.]

    Hello all,

    I'm having a problem with IPAddr, and I'm hoping someone can explain it to
    me. I've done the following test, and I get the results shown below.

    irb(main):001:0> require 'ipaddr'
    => true
    irb(main):002:0> net_1 = IPAddr.new("192.168.0.0/16")
    => #<IPAddr: IPv4:192.168.0.0/255.255.0.0>
    irb(main):003:0> net_2 = IPAddr.new("192.168.0.0/24")
    => #<IPAddr: IPv4:192.168.0.0/255.255.255.0>
    irb(main):004:0> net_1.include?(net_2)
    => true
    irb(main):005:0> net_2.include?(net_1)
    => true
    irb(main):006:0>

    I understand how net_1 can include net_2, but why does net_2 include
    net_1?! Thanks in advance! -- BTR
     
    Bryan Richardson, Jan 16, 2008
    #1
    1. Advertising

  2. Bryan Richardson

    Gary Wright Guest

    On Jan 16, 2008, at 12:02 AM, Bryan Richardson wrote:

    > Hello all,
    >
    > I'm having a problem with IPAddr, and I'm hoping someone can
    > explain it to
    > me. I've done the following test, and I get the results shown below.
    >
    > irb(main):001:0> require 'ipaddr'
    > => true
    > irb(main):002:0> net_1 = IPAddr.new("192.168.0.0/16")
    > => #<IPAddr: IPv4:192.168.0.0/255.255.0.0>
    > irb(main):003:0> net_2 = IPAddr.new("192.168.0.0/24")
    > => #<IPAddr: IPv4:192.168.0.0/255.255.255.0>
    > irb(main):004:0> net_1.include?(net_2)
    > => true
    > irb(main):005:0> net_2.include?(net_1)
    > => true
    > irb(main):006:0>


    It is because include? is treating its argument as an address not as
    a network. The subnet mask of the argument is ignored. So
    net_2.include?(net_1) is really asking whether the first address of
    net_1 (192.168.0.0) is contained in net_2 and that is true.

    Gary Wright
     
    Gary Wright, Jan 16, 2008
    #2
    1. Advertising

  3. [Note: parts of this message were removed to make it a legal post.]

    Gary,

    Thanks for the reply. Here's what I get when I try something else:

    irb(main):001:0> require 'ipaddr'
    => true
    irb(main):002:0> net_1 = IPAddr.new("192.168.0.0/16")
    => #<IPAddr: IPv4:192.168.0.0/255.255.0.0>
    irb(main):003:0> net_2 = IPAddr.new("192.168.101.0/24")
    => #<IPAddr: IPv4:192.168.101.0/255.255.255.0>
    irb(main):004:0> net_1.include?(net_2)
    => true
    irb(main):005:0> net_2.include?(net_1)
    => false
    irb(main):006:0>

    Makes sense I guess. Is there any way to tell IPAddr to look at it as a
    network instead of as an address? I have a situation where I may come
    across an address (ending in .0, so defining a network) where the netmask
    isn't given, so I assign it as a small network (say /29). Later on I may
    come across it again, this time with the netmask defined (say /16), and I
    want to merge the first one into the second one. Therefore, each time I add
    a new network to my database, I compare it to the existing ones to see if
    any should be merged. Any suggestions? Thanks!! -- BTR

    On Jan 15, 2008 10:32 PM, Gary Wright <> wrote:

    >
    > On Jan 16, 2008, at 12:02 AM, Bryan Richardson wrote:
    >
    > > Hello all,
    > >
    > > I'm having a problem with IPAddr, and I'm hoping someone can
    > > explain it to
    > > me. I've done the following test, and I get the results shown below.
    > >
    > > irb(main):001:0> require 'ipaddr'
    > > => true
    > > irb(main):002:0> net_1 = IPAddr.new("192.168.0.0/16")
    > > => #<IPAddr: IPv4:192.168.0.0/255.255.0.0>
    > > irb(main):003:0> net_2 = IPAddr.new("192.168.0.0/24")
    > > => #<IPAddr: IPv4:192.168.0.0/255.255.255.0>
    > > irb(main):004:0> net_1.include?(net_2)
    > > => true
    > > irb(main):005:0> net_2.include?(net_1)
    > > => true
    > > irb(main):006:0>

    >
    > It is because include? is treating its argument as an address not as
    > a network. The subnet mask of the argument is ignored. So
    > net_2.include?(net_1) is really asking whether the first address of
    > net_1 (192.168.0.0) is contained in net_2 and that is true.
    >
    > Gary Wright
    >
    >
    >
     
    Bryan Richardson, Jan 16, 2008
    #3
  4. Bryan Richardson

    Todd Benson Guest

    On Jan 15, 2008 11:53 PM, Bryan Richardson <> wrote:
    > Gary,
    >
    > Thanks for the reply. Here's what I get when I try something else:
    >
    > irb(main):001:0> require 'ipaddr'
    > => true
    > irb(main):002:0> net_1 = IPAddr.new("192.168.0.0/16")
    > => #<IPAddr: IPv4:192.168.0.0/255.255.0.0>
    > irb(main):003:0> net_2 = IPAddr.new("192.168.101.0/24")
    > => #<IPAddr: IPv4:192.168.101.0/255.255.255.0>
    > irb(main):004:0> net_1.include?(net_2)
    > => true
    > irb(main):005:0> net_2.include?(net_1)
    > => false
    > irb(main):006:0>
    >
    > Makes sense I guess. Is there any way to tell IPAddr to look at it as a
    > network instead of as an address? I have a situation where I may come
    > across an address (ending in .0, so defining a network) where the netmask
    > isn't given, so I assign it as a small network (say /29). Later on I may
    > come across it again, this time with the netmask defined (say /16), and I
    > want to merge the first one into the second one. Therefore, each time I add
    > a new network to my database, I compare it to the existing ones to see if
    > any should be merged. Any suggestions? Thanks!! -- BTR


    You could open up IPAddr to get at the mask for comparison.

    class IPAddr
    def net
    @mask_addr
    end
    end

    ip1 = IPAddr.new("192.168.0.0/16")
    ip2 = IPAddr.new("192.168.0.0/24")

    ip1.net > ip2.net # => false (which seems contradictory, but the mask
    number is larger for smaller networks)
    ip2.net > ip1.net #=> true

    hth,
    Todd
     
    Todd Benson, Jan 16, 2008
    #4
  5. Bryan Richardson

    fw Guest

    On Wed, 2008-01-16 at 14:53 +0900, Bryan Richardson wrote:
    > Gary,
    >
    > Thanks for the reply. Here's what I get when I try something else:
    >
    > irb(main):001:0> require 'ipaddr'
    > => true
    > irb(main):002:0> net_1 = IPAddr.new("192.168.0.0/16")
    > => #<IPAddr: IPv4:192.168.0.0/255.255.0.0>
    > irb(main):003:0> net_2 = IPAddr.new("192.168.101.0/24")
    > => #<IPAddr: IPv4:192.168.101.0/255.255.255.0>
    > irb(main):004:0> net_1.include?(net_2)
    > => true
    > irb(main):005:0> net_2.include?(net_1)
    > => false
    > irb(main):006:0>
    >
    > Makes sense I guess. Is there any way to tell IPAddr to look at it as a
    > network instead of as an address? I have a situation where I may come
    > across an address (ending in .0, so defining a network) where the netmask
    > isn't given, so I assign it as a small network (say /29). Later on I may
    > come across it again, this time with the netmask defined (say /16), and I
    > want to merge the first one into the second one. Therefore, each time I add
    > a new network to my database, I compare it to the existing ones to see if
    > any should be merged. Any suggestions? Thanks!! -- BTR


    First I'd like to add that the last octet being 0 does not mean that the
    IP address is a network address: In the network 10.0.0.0/25, 10.0.1.0 is
    a host address.

    IPAddr doesn't seem to have this functionality, but you can add it like
    this:

    $ irb
    irb(main):001:0> require 'ipaddr'
    => true
    irb(main):002:0> class IPAddr
    irb(main):003:1> def broadcast_addr
    irb(main):004:2> _to_string(@addr | (2**32 - 1) - (@mask_addr))
    irb(main):005:2> end
    irb(main):006:1> def network_in_network?(network)
    irb(main):007:2> return false unless self.include?(network)
    irb(main):008:2> return false unless
    self.include?(IPAddr.new(network.broadcast_addr))
    irb(main):009:2> return true
    irb(main):010:2> end
    irb(main):011:1> end
    => nil
    irb(main):012:0> a = IPAddr.new('192.168.0.128/25')
    => #<IPAddr: IPv4:192.168.0.128/255.255.255.128>
    irb(main):013:0> b = IPAddr.new('192.168.0.0/24')
    => #<IPAddr: IPv4:192.168.0.0/255.255.255.0>
    irb(main):014:0> a.network_in_network?(b)
    => false
    irb(main):015:0> b.network_in_network?(a)
    => true
    irb(main):016:0>


    This works by determining the broadcast address of the network (by ORing
    the network address with the reverse netmask) and then checking if both
    network and broadcast address are included in the range you're checking
    against.

    HTH,

    Felix
     
    fw, Jan 16, 2008
    #5
  6. Bryan Richardson

    Todd Benson Guest

    On Jan 16, 2008 6:52 AM, fw <> wrote:
    > On Wed, 2008-01-16 at 14:53 +0900, Bryan Richardson wrote:
    > > Gary,
    > >
    > > Thanks for the reply. Here's what I get when I try something else:
    > >
    > > irb(main):001:0> require 'ipaddr'
    > > => true
    > > irb(main):002:0> net_1 = IPAddr.new("192.168.0.0/16")
    > > => #<IPAddr: IPv4:192.168.0.0/255.255.0.0>
    > > irb(main):003:0> net_2 = IPAddr.new("192.168.101.0/24")
    > > => #<IPAddr: IPv4:192.168.101.0/255.255.255.0>
    > > irb(main):004:0> net_1.include?(net_2)
    > > => true
    > > irb(main):005:0> net_2.include?(net_1)
    > > => false
    > > irb(main):006:0>
    > >
    > > Makes sense I guess. Is there any way to tell IPAddr to look at it as a
    > > network instead of as an address? I have a situation where I may come
    > > across an address (ending in .0, so defining a network) where the netmask
    > > isn't given, so I assign it as a small network (say /29). Later on I may
    > > come across it again, this time with the netmask defined (say /16), and I
    > > want to merge the first one into the second one. Therefore, each time I add
    > > a new network to my database, I compare it to the existing ones to see if
    > > any should be merged. Any suggestions? Thanks!! -- BTR

    >
    > First I'd like to add that the last octet being 0 does not mean that the
    > IP address is a network address: In the network 10.0.0.0/25, 10.0.1.0 is
    > a host address.
    >
    > IPAddr doesn't seem to have this functionality, but you can add it like
    > this:
    >
    > $ irb
    > irb(main):001:0> require 'ipaddr'
    > => true
    > irb(main):002:0> class IPAddr
    > irb(main):003:1> def broadcast_addr
    > irb(main):004:2> _to_string(@addr | (2**32 - 1) - (@mask_addr))
    > irb(main):005:2> end
    > irb(main):006:1> def network_in_network?(network)
    > irb(main):007:2> return false unless self.include?(network)
    > irb(main):008:2> return false unless
    > self.include?(IPAddr.new(network.broadcast_addr))
    > irb(main):009:2> return true
    > irb(main):010:2> end
    > irb(main):011:1> end
    > => nil
    > irb(main):012:0> a = IPAddr.new('192.168.0.128/25')
    > => #<IPAddr: IPv4:192.168.0.128/255.255.255.128>
    > irb(main):013:0> b = IPAddr.new('192.168.0.0/24')
    > => #<IPAddr: IPv4:192.168.0.0/255.255.255.0>
    > irb(main):014:0> a.network_in_network?(b)
    > => false
    > irb(main):015:0> b.network_in_network?(a)
    > => true
    > irb(main):016:0>
    >
    >
    > This works by determining the broadcast address of the network (by ORing
    > the network address with the reverse netmask) and then checking if both
    > network and broadcast address are included in the range you're checking
    > against.


    This might work too...

    class IPAddr
    attr_accessor :mask_addr
    def network_in_network? ipaddr
    @mask_addr > ipaddr.mask_addr
    end
    end

    Todd
     
    Todd Benson, Jan 16, 2008
    #6
  7. [Note: parts of this message were removed to make it a legal post.]

    Todd,

    I believe Felix's suggestion is the way to go. With yours, the addresses
    could be different, but as long as the mask was bigger it would still return
    true... not correct. Example:

    a = IPAddr.new("192.168.15.5")
    b = IPAddr.new("192.168.16.0/24")

    a.network_in_network?(b) #==> true

    Thanks! -- BTR

    On Jan 16, 2008 4:59 PM, Todd Benson <> wrote:

    > On Jan 16, 2008 6:52 AM, fw <> wrote:
    > > On Wed, 2008-01-16 at 14:53 +0900, Bryan Richardson wrote:
    > > > Gary,
    > > >
    > > > Thanks for the reply. Here's what I get when I try something else:
    > > >
    > > > irb(main):001:0> require 'ipaddr'
    > > > => true
    > > > irb(main):002:0> net_1 = IPAddr.new("192.168.0.0/16")
    > > > => #<IPAddr: IPv4:192.168.0.0/255.255.0.0>
    > > > irb(main):003:0> net_2 = IPAddr.new("192.168.101.0/24")
    > > > => #<IPAddr: IPv4:192.168.101.0/255.255.255.0>
    > > > irb(main):004:0> net_1.include?(net_2)
    > > > => true
    > > > irb(main):005:0> net_2.include?(net_1)
    > > > => false
    > > > irb(main):006:0>
    > > >
    > > > Makes sense I guess. Is there any way to tell IPAddr to look at it as

    > a
    > > > network instead of as an address? I have a situation where I may come
    > > > across an address (ending in .0, so defining a network) where the

    > netmask
    > > > isn't given, so I assign it as a small network (say /29). Later on I

    > may
    > > > come across it again, this time with the netmask defined (say /16),

    > and I
    > > > want to merge the first one into the second one. Therefore, each time

    > I add
    > > > a new network to my database, I compare it to the existing ones to see

    > if
    > > > any should be merged. Any suggestions? Thanks!! -- BTR

    > >
    > > First I'd like to add that the last octet being 0 does not mean that the
    > > IP address is a network address: In the network 10.0.0.0/25, 10.0.1.0 is
    > > a host address.
    > >
    > > IPAddr doesn't seem to have this functionality, but you can add it like
    > > this:
    > >
    > > $ irb
    > > irb(main):001:0> require 'ipaddr'
    > > => true
    > > irb(main):002:0> class IPAddr
    > > irb(main):003:1> def broadcast_addr
    > > irb(main):004:2> _to_string(@addr | (2**32 - 1) - (@mask_addr))
    > > irb(main):005:2> end
    > > irb(main):006:1> def network_in_network?(network)
    > > irb(main):007:2> return false unless self.include?(network)
    > > irb(main):008:2> return false unless
    > > self.include?(IPAddr.new(network.broadcast_addr))
    > > irb(main):009:2> return true
    > > irb(main):010:2> end
    > > irb(main):011:1> end
    > > => nil
    > > irb(main):012:0> a = IPAddr.new('192.168.0.128/25'<http://192.168.0.128/25%27>

    > )
    > > => #<IPAddr: IPv4:192.168.0.128/255.255.255.128>
    > > irb(main):013:0> b = IPAddr.new('192.168.0.0/24'<http://192.168.0.0/24%27>

    > )
    > > => #<IPAddr: IPv4:192.168.0.0/255.255.255.0>
    > > irb(main):014:0> a.network_in_network?(b)
    > > => false
    > > irb(main):015:0> b.network_in_network?(a)
    > > => true
    > > irb(main):016:0>
    > >
    > >
    > > This works by determining the broadcast address of the network (by ORing
    > > the network address with the reverse netmask) and then checking if both
    > > network and broadcast address are included in the range you're checking
    > > against.

    >
    > This might work too...
    >
    > class IPAddr
    > attr_accessor :mask_addr
    > def network_in_network? ipaddr
    > @mask_addr > ipaddr.mask_addr
    > end
    > end
    >
    > Todd
    >
    >
     
    Bryan Richardson, Jan 17, 2008
    #7
  8. Bryan Richardson

    Todd Benson Guest

    On Jan 16, 2008 9:12 PM, Bryan Richardson <> wrote:
    > Todd,
    >
    > I believe Felix's suggestion is the way to go. With yours, the addresses
    > could be different, but as long as the mask was bigger it would still return
    > true... not correct.


    Good point!

    thanx,
    Todd
     
    Todd Benson, Jan 17, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Neil Spring

    IPAddr as hashtable key?

    Neil Spring, Jan 12, 2004, in forum: Ruby
    Replies:
    0
    Views:
    143
    Neil Spring
    Jan 12, 2004
  2. Markus Werner

    Standardlib "ipaddr.rb"

    Markus Werner, Jan 3, 2005, in forum: Ruby
    Replies:
    6
    Views:
    191
    Austin Ziegler
    Jan 7, 2005
  3. Bug in ipaddr.rb

    , Aug 26, 2005, in forum: Ruby
    Replies:
    2
    Views:
    130
    David Roberts
    Aug 26, 2005
  4. Hadmut Danisch

    Maintainer of ipaddr.rb ?

    Hadmut Danisch, Dec 13, 2005, in forum: Ruby
    Replies:
    2
    Views:
    123
    Gyoung-Yoon Noh
    Dec 13, 2005
  5. Markus Werner

    stdlib ipaddr request for comment;-)

    Markus Werner, Dec 29, 2005, in forum: Ruby
    Replies:
    2
    Views:
    204
    Markus Werner
    Dec 30, 2005
Loading...

Share This Page