[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Problem with IPAddr

Bryan Richardson

1/16/2008 5:03:00 AM

[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

7 Answers

Gary Wright

1/16/2008 5:33:00 AM

0


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

1/16/2008 5:53:00 AM

0

[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 <gwtmp01@mac.com> 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
>
>
>

Todd Benson

1/16/2008 11:02:00 AM

0

On Jan 15, 2008 11:53 PM, Bryan Richardson <btricha@gmail.com> 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

Felix Windt

1/16/2008 12:53:00 PM

0

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


Todd Benson

1/16/2008 11:59:00 PM

0

On Jan 16, 2008 6:52 AM, fw <fwmailinglists@gmail.com> 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

Bryan Richardson

1/17/2008 3:13:00 AM

0

[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 <caduceass@gmail.com> wrote:

> On Jan 16, 2008 6:52 AM, fw <fwmailinglists@gmail.com> 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...
> )
> > => #<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...
> )
> > => #<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

1/17/2008 9:09:00 AM

0

On Jan 16, 2008 9:12 PM, Bryan Richardson <btricha@gmail.com> 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