# Cidr.rb: port of Perl's Net::CIDR v0.11 available

**URL:** <https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630>\
**Category:** Ruby\
**Created:** [November 29, 2006, 8:44am UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630 "2006-11-29T08:44:23Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [November 29, 2006, 8:44am UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/1 "2006-11-29T08:44:23Z")

</div>

Module:

```
http://www.catnook.com/programs/cidr.rb

```

Simple test program:

```
http://www.catnook.com/programs/cidrtest.rb

```

Not sure about the license. Hope this is useful to someone.

As an aside: anyone have a port of Net::Ping they are willing to share?  
I’m  
trying to convert some code (and colleagues!) to Ruby and am running  
into the  
“missing libraries” issue…

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [November 29, 2006, 9:36am UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/2 "2006-11-29T09:36:29Z")

</div>

Hi,

> As an aside: anyone have a port of Net::Ping they are willing to share? I’m  
> trying to convert some code (and colleagues!) to Ruby and am running into the  
> “missing libraries” issue…

Check the RAA (and Rubyforge).

For ping, there is ‘ping’ in the standard library, and ‘net/ping’ on the  
RAA (‘gem install net-ping’).

Pat Eyler wrote in May about pushing an ICMP-capable version of net/ping  
into the standard library for 1.8.6.

Cheers,  
Dave

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [November 29, 2006, 5:07pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/3 "2006-11-29T17:07:45Z")

</div>

Dave B. wrote:

> Pat Eyler wrote in May about pushing an ICMP-capable version of net/ping  
> into the standard library for 1.8.6.
> 
> Cheers,  
> Dave

Indeed, Pat talked to me about possibly including net-ping in the  
standard lib, though it needs a PingICMP class. It could probably  
stand a bit of reorganization, too.

In fact, I still have some code laying around that Sean C. sent  
to me a long time ago. Maybe it’s time to revisit that. 🙂

Regards,

Dan

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [November 29, 2006, 5:13pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/4 "2006-11-29T17:13:45Z")

</div>

On 11/29/06, Daniel B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Dave B. wrote:
> 
> > For ping, there is ‘ping’ in the standard library, and ‘net/ping’ on the  
> > RAA (‘gem install net-ping’).

ugh! I hate ping.

> 

I’ve actually done some work on the code, but it’s in need of some  
documentation and a bit more polish. The ICMP ping still needs  
to be integrated as well.

I just have more ambition than time, talent, and energy. ☹

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [November 29, 2006, 10:27pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/5 "2006-11-29T22:27:08Z")

</div>

pat eyler wrote:

> > stand a bit of reorganization, too.
> 
> I’ve actually done some work on the code, but it’s in need of some  
> documentation and a bit more polish. The ICMP ping still needs  
> to be integrated as well.
> 
> I just have more ambition than time, talent, and energy. ☹

It sounds simple enough for a Ruby Q… Then we’d have not two, but a  
dozen versions, possibly including a Net::Ping-interfaced one for Jos!

Dave

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [November 29, 2006, 10:43pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/6 "2006-11-29T22:43:10Z")

</div>

On Nov 29, 2006, at 3:25 PM, Dave B. wrote:

> > > Indeed, Pat talked to me about possibly including net-ping in the  
> > > dozen versions, possibly including a Net::Ping-interfaced one for Jos!  
> > > I’m a huge fan of using the Ruby Q. to improve libraries like  
> > > this. I’m a Ping Dummy, so you guys put your heads together and  
> > > write up something that explains the goals and if I can understand  
> > > them, we’ve got a winner.

It takes a lot less time, talent, and energy to define the problem  
well enough to get help from the whole community and the results  
never cease to dazzle me…

James Edward G. II

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [November 30, 2006, 4:22pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/7 "2006-11-30T16:22:08Z")

</div>

Jos B. wrote:

> > > 
> > 
> > Check the RAA (and Rubyforge).
> > 
> > For ping, there is ‘ping’ in the standard library, and ‘net/ping’ on the  
> > RAA (‘gem install net-ping’).
> 
> I’m aware of those but they lack some features the Perl version has. Notably  
> ICMP support and returning timing information.

Well, there is PingExternal for ICMP support. 😉

Seriously, though, both would be good additions.

> It would also be nice for there to be a single Net::Ping class, just like the  
> Perl version provides, wrapping/hiding the specialized classes. That seems  
> like an easy addition.

The API was modelled after the current ping.rb in the standard library  
to try to keep things consistant and more portable for anyone switching  
from ping.rb to my net-ping module. A factory pattern should be doable  
if that’s what folks want. In practice, however, I don’t see it as a  
major issue, and probably not worth the API breakage.

Regards,

Dan

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [November 29, 2006, 6:58pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/8 "2006-11-29T18:58:21Z")

</div>

Hi Dave,

On Wed, Nov 29, 2006 at 05:35:13PM +0900, Dave B. wrote:

> Hi,
> 
> > As an aside: anyone have a port of Net::Ping they are willing to share? I’m  
> > trying to convert some code (and colleagues!) to Ruby and am running into the  
> > “missing libraries” issue…
> 
> Check the RAA (and Rubyforge).
> 
> For ping, there is ‘ping’ in the standard library, and ‘net/ping’ on the  
> RAA (‘gem install net-ping’).

I’m aware of those but they lack some features the Perl version has.  
Notably  
ICMP support and returning timing information.

It would also be nice for there to be a single Net::Ping class, just  
like the  
Perl version provides, wrapping/hiding the specialized classes. That  
seems  
like an easy addition.

> Pat Eyler wrote in May about pushing an ICMP-capable version of net/ping  
> into the standard library for 1.8.6.

/me crosses fingers…

Cheers,

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [November 30, 2006, 6:36pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/9 "2006-11-30T18:36:34Z")

</div>

On Fri, Dec 01, 2006 at 12:20:36AM +0900, Daniel B. wrote:  
[snip]

> > I’m aware of those but they lack some features the Perl version has.  
> > Notably  
> > ICMP support and returning timing information.
> 
> Well, there is PingExternal for ICMP support. 😉
> 
> Seriously, though, both would be good additions.

Indeed.

> > It would also be nice for there to be a single Net::Ping class, just like  
> > the  
> > Perl version provides, wrapping/hiding the specialized classes. That seems  
> > like an easy addition.
> 
> The API was modelled after the current ping.rb in the standard library  
> to try to keep things consistant and more portable for anyone switching  
> from ping.rb to my net-ping module. A factory pattern should be doable  
> if that’s what folks want. In practice, however, I don’t see it as a  
> major issue, and probably not worth the API breakage.

It eases the transition from Perl, as in my case. If you mean something  
like  
the following then that would be great:

```
lizzy:/tmp% cat r
class Ping
  def self.create(type, *args)
case type
when :foo
  FooPing.new
when :bar
  BarPing.new
end
  end
end

class FooPing < Ping
  def ping(host)
puts "#{self.class}: pinging #{host}"
  end
end

class BarPing < Ping
  def ping(host)
puts "#{self.class}: pinging #{host}"
  end
end

pinger = Ping.create(:bar)
pinger.ping("myhost")
lizzy:/tmp% ruby r
BarPing: pinging myhost
lizzy:/tmp%

```

Let me know what I can do to help move this along.

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [December 1, 2006, 8:41pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/10 "2006-12-01T20:41:28Z")

</div>

On Fri, Dec 01, 2006 at 04:47:05AM +0900, Daniel B. wrote:

> Well, you could start by porting the ping\_icmp() function from Ping.pm  
> to Ruby. I started working on it but I got stuck and I need to work on  
> other things. Below is what I’ve got so far:

I’ve made some progress; see attached. Let me know what you think.

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [November 30, 2006, 8:49pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/11 "2006-11-30T20:49:09Z")

</div>

Jos B. wrote:

\> when :foo \> end \> lizzy:/tmp% ruby r \> BarPing: pinging myhost \> lizzy:/tmp% \> \> Let me know what I can do to help move this along. \> \> Well, you could start by porting the ping\_icmp() function from Ping.pm to Ruby. I started working on it but I got stuck and I need to work on other things. Below is what I've got so far:

require ‘net/ping’

module Net  
class Ping::ICMP \< Ping

```
  ICMP_ECHOREPLY = 0
  ICMP_ECHO = 8
  ICMP_SUBCODE = 0
  ICMP_FLAGS = 0
  ICMP_PORT = 0

  def initialize(*args)
     super(args)
     raise 'requires root privileges' if Process.euid > 0 # unsure
     @seq = 0
     @data_size = 0
     @data = ""
  end

  def checksum(msg)
     length = msg.length
     num_short = length / 2
     check = 0

     msg.unpack("n#{num_short}").each do |short|
        check += short
     end

     if length % 2 > 0
        check += msg[length-1, 1].unpack('C') << 8
     end

     check = (check >> 16) + (check & 0xffff)
     return (~((check >> 16) + check) & 0xffff)
  end

  def ping
     socket = Socket.new(
        Socket::PF_INET,
        Socket::SOCK_RAW,
        Socket::IPPROTO_ICMP
     )

     @seq = (@seq + 1) % 65536
     checksum = 0

     pstring = "C2 n3 A" << @data_size.to_s
     pid = Process.pid

     msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, pid, @seq,

```

@data].pack(pstring)  
# TODO: finish  
end  
end  
end

Regards,

Dan

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [December 1, 2006, 8:55pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/12 "2006-12-01T20:55:30Z")

</div>

Jos B. wrote:

> ```
> ICMP_STRUCT = 'C2 n3 A'
> @pid = Process.pid & 0xffff
> 
> socket = Socket.new(
> checksum = checksum(msg)
> 
> from_pid = -1
> if recv_msg.length >= 56
> done = true
> 
> ```
> 
> end
> 
> p = Net::Ping::ICMP.new  
> p p.ping(ARGV.shift, 5)

Seems to work. Mind if I include with the next release of net-ping  
(with acknowledgements, of course).

The only tweak I would make are to have it return true or false, instead  
of 1 or nil.

Regards,

Dan

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [December 1, 2006, 9:37pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/13 "2006-12-01T21:37:38Z")

</div>

On Sat, Dec 02, 2006 at 04:54:49AM +0900, Daniel B. wrote:

> Jos B. wrote:  
> Seems to work. Mind if I include with the next release of net-ping  
> (with acknowledgements, of course).

Of course, thanks Daniel.

> The only tweak I would make are to have it return true or false, instead  
> of 1 or nil.

Good idea. Now, the Perl Net::Ping library returns duration:

```
($ret, $duration, $ip) = $p->ping($host, $timeout);

In array context, the elapsed time as well as the string form of the 

```

ip  
the host resolved to are also returned.

What would be the best way to add that to the Ruby version? Obviously  
one  
would want all Net::Ping classes to support this. I have a local utility  
that  
uses this information, which is why I need it.

Cheers,

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [December 1, 2006, 10:05pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/14 "2006-12-01T22:05:44Z")

</div>

Jos B. wrote:

> On Sat, Dec 02, 2006 at 04:54:49AM +0900, Daniel B. wrote:
> 
> > Jos B. wrote:  
> > Seems to work. Mind if I include with the next release of net-ping  
> > (with acknowledgements, of course).
> 
> Of course, thanks Daniel.

Great, thanks.

> What would be the best way to add that to the Ruby version? Obviously one  
> would want all Net::Ping classes to support this. I have a local utility that  
> uses this information, which is why I need it.
> 
> Cheers,

Hm, I’ll have to think about the API. I suppose the most simple  
approach is to just add accessors for duration and ip\_address (with a  
‘nil’ value by default). In practice, then, your code would look like  
this:

if p.ping?  
puts p.ip\_address  
puts p.duration  
end

How does that look?

Regards,

Dan

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [December 1, 2006, 10:15pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/15 "2006-12-01T22:15:47Z")

</div>

On Sat, Dec 02, 2006 at 06:03:59AM +0900, Daniel B. wrote:

> Hm, I’ll have to think about the API. I suppose the most simple  
> approach is to just add accessors for duration and ip\_address (with a  
> ‘nil’ value by default). In practice, then, your code would look like this:
> 
> if p.ping?  
> puts p.ip\_address  
> puts p.duration  
> end
> 
> How does that look?

I like this much better than the positional API that Perl uses here (“Is  
duration the 1st or 2nd return value?”). Plus it makes it easy to add  
futher  
items down the road without breaking existing code. +1.

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [December 2, 2006, 6:17pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/16 "2006-12-02T18:17:46Z")

</div>

On Sat, Dec 02, 2006 at 08:50:12PM +0900, Daniel B. wrote:

> Ok, I’ll add those. However, don’t put too much stock in the duration.  
> Looking at the Perl code, it isn’t much more than this:
> 
> start = Time.now  
> p.ping?  
> duration = Time.now - start

True, but one would want the timing measurement to be done as close as  
possible around the send and the recvfrom, eliminating the avoidable  
overhead  
of the method call and setup inside it being included in the duration.  
Plus,  
having .duration is convenient, no?

> And you can get the ip via IPSocket.getaddress(host)

Agreed. That functionality doesn’t belong in this module.

---

<div class="post-metadata">

**Author:** ![Jos\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/779978/32.png) [@Jos\_B](https://www.ruby-forum.com/u/Jos_B)\
**Post date:** [December 2, 2006, 12:51pm UTC](https://www.ruby-forum.com/t/cidr-rb-port-of-perls-net-cidr-v0-11-available/77630/17 "2006-12-02T12:51:11Z")

</div>

Jos B. wrote:

> > How does that look?
> 
> I like this much better than the positional API that Perl uses here (“Is  
> duration the 1st or 2nd return value?”). Plus it makes it easy to add futher  
> items down the road without breaking existing code. +1.

Ok, I’ll add those. However, don’t put too much stock in the duration.  
Looking at the Perl code, it isn’t much more than this:

start = Time.now  
p.ping?  
duration = Time.now - start

And you can get the ip via IPSocket.getaddress(host)

Regards,

Dan
