使いにくいというか、ネットワーク向きではない?
だからいくつかメソッドを追加してみた。
追加したメソッド
cidr
selfのCIDRを返す。
なんでこれが取得出来ないのか不思議な位。
host_count
selfのネットワークに存在するホスト数。
network
selfが存在するネットワークアドレスを返す。
第1引数でCIDRの変更も出来る。
broadcast
selfが存在するブロードキャストアドレスを返す。
第1引数でCIDRの変更も出来る。
ソース
#!/usr/bin/ruby require 'ipaddr' require 'ping' class IPAddr # Bit数 def bit_count case @family when Socket::AF_INET return 32 when Socket::AF_INET6 return 128 end end # CIDR def cidr cidr = 0 i = 0 bit = self.bit_count loop do if 0 < ((1<<i) & @mask_addr) return bit - i elsif bit<=i return 0 end i += 1 end end # ネットワークのホスト数 def host_count return 2 ** (self.bit_count - self.cidr) end # ネットワークアドレス def network(cidr=nil) unless cidr cidr = IPAddr.new(@mask_addr, @family).to_s end return IPAddr.new("#{self.to_s}/#{cidr}") end # ブロードキャストアドレス def broadcast(cidr=nil) net = self.network(cidr) return net + net.host_count - 1 end # 演算子 + def +(o) return IPAddr.new(self.to_i + o.to_i, @family) end # 演算子 - def -(o) return IPAddr.new(self.to_i - o.to_i, @family) end end class BroadcastPing def initialize(ipaddr) @ipaddr = ipaddr @t = [] @ping = {} end def start network = @ipaddr.network broadcast = @ipaddr.broadcast i = 0 loop do ip = network + i if @ipaddr.include?(ip) @t.push(Thread.new { @ping[ip] = self.run(ip) }) else break end i += 1 end end def join @t.each {|t| t.join} end def show @ping.keys.sort.each { |ip| result = @ping[ip] puts "#{ip}: #{result}" } end def run(ip) return Ping.pingecho(ip.to_s) end end def main network = nil begin network = IPAddr.new(ARGV.shift) rescue puts "Usage: bping.rb addr/cidr" return end bp = BroadcastPing.new(network) bp.start bp.join bp.show end main