From: Todd Benson Date: 2008-01-17T08:59:16+09:00 Subject: Re: Problem with IPAddr 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") > > => # > > irb(main):003:0> net_2 = IPAddr.new("192.168.101.0/24") > > => # > > 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') > => # > irb(main):013:0> b = IPAddr.new('192.168.0.0/24') > => # > 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