From 1395eee4d022c90adebf9eaf7f3e70a65411449b Mon Sep 17 00:00:00 2001 From: Marco Ceresa Date: Sat, 22 May 2010 17:17:31 +0100 Subject: Finished documentation for IPAddress::Prefix, README and IPAddress::IPBase --- lib/ipaddress.rb | 29 ++++++++++++++ lib/ipaddress/ipbase.rb | 27 +++++++++++-- lib/ipaddress/prefix.rb | 102 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 151 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/ipaddress.rb b/lib/ipaddress.rb index 00a1eee..50336f0 100644 --- a/lib/ipaddress.rb +++ b/lib/ipaddress.rb @@ -5,6 +5,35 @@ require 'ipaddress/ipbase' require 'ipaddress/ipv4' require 'ipaddress/ipv6' +# +# IPAddress is a wrapper method built around +# IPAddress's library classes. Its purpouse is to +# make you indipendent from the type of IP address +# you're going to use. +# +# For example, instead of creating the three types +# of IP addresses using their own contructors +# +# ip = IPAddress::IPv4.new "172.16.10.1/24" +# ip6 = IPAddress::IPv6.new "2001:db8::8:800:200c:417a/64" +# ip_mapped = IPAddress::IPv6::Mapped "::ffff:172.16.10.1/128" +# +# you can just use the IPAddress wrapper: +# +# ip = IPAddress "172.16.10.1/24" +# ip6 = IPAddress "2001:db8::8:800:200c:417a/64" +# ip_mapped = IPAddress "::ffff:172.16.10.1/128" +# +# All the object created will be instances of the +# correct class: +# +# ip.class +# #=> IPAddress::IPv4 +# ip6.class +# #=> IPAddress::IPv6 +# ip_mapped.class +# #=> IPAddress::IPv6::Mapped +# def IPAddress(str) case str when /:.+\./ diff --git a/lib/ipaddress/ipbase.rb b/lib/ipaddress/ipbase.rb index 0c47177..91e596f 100644 --- a/lib/ipaddress/ipbase.rb +++ b/lib/ipaddress/ipbase.rb @@ -17,7 +17,18 @@ module IPAddress def self.valid?(addr) valid_ipv4?(addr) || valid_ipv6?(addr) end - + + # + # Checks if the given string is a valid IPv4 address + # + # Example: + # + # IPAddress::valid_ipv4? "2002::1" + # #=> false + # + # IPAddress::valid_ipv4? "172.16.10.1" + # #=> true + # def self.valid_ipv4?(addr) if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr return $~.captures.all? {|i| i.to_i < 256} @@ -39,6 +50,17 @@ module IPAddress return false end + # + # Checks if the given string is a valid IPv6 address + # + # Example: + # + # IPAddress::valid_ipv6? "2002::1" + # #=> true + # + # IPAddress::valid_ipv6? "2002::DEAD::BEEF" + # #=> false + # def self.valid_ipv6?(addr) # IPv6 (normal) return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*\Z/ =~ addr @@ -51,9 +73,6 @@ module IPAddress false end - class IPBase - end - end # module IPAddress diff --git a/lib/ipaddress/prefix.rb b/lib/ipaddress/prefix.rb index 6addd75..61e684b 100644 --- a/lib/ipaddress/prefix.rb +++ b/lib/ipaddress/prefix.rb @@ -12,9 +12,12 @@ module IPAddress # =DESCRIPTION # # IPAddresS::Prefix is the parent class for IPAddress::Prefix32 - # and IPAddress::Prefix128, - - + # and IPAddress::Prefix128, defining some modules in common for + # both the subclasses. + # + # IPAddress::Prefix shouldn't be accesses directly, unless + # for particular needs. + # class Prefix include Comparable @@ -43,6 +46,12 @@ module IPAddress class Prefix32 < Prefix + # + # Creates a new prefix object for 32 bits IPv4 addresses + # + # prefix = IPAddress::Prefix32.new 24 + # #=> 24 + # def initialize(num) unless (1..32).include? num raise ArgumentError, "Prefix must be in range 1..128, got: #{num}" @@ -50,30 +59,92 @@ module IPAddress super(num) end + # + # Transforms the prefix into a string of bits + # representing the netmask + # + # prefix = IPAddress::Prefix32.new 24 + # + # prefix.bits + # #=> "11111111111111111111111100000000" + # def bits "1" * @prefix + "0" * (32 - @prefix) end + # + # Gives the prefix in IPv4 dotted decimal format, + # i.e. the canonical netmask we're all used to + # + # prefix = IPAddress::Prefix32.new 24 + # + # prefix.to_ip + # #=> "255.255.255.0" + # def to_ip [bits].pack("B*").unpack("CCCC").join(".") end + # + # An array of octets of the IPv4 dotted decimal + # format + # + # prefix = IPAddress::Prefix32.new 24 + # + # prefix.octets + # #=> [255, 255, 255, 0] + # def octets to_ip.split(".").map{|i| i.to_i} end + # + # Unsigned 32 bits decimal number representing + # the prefix + # + # prefix = IPAddress::Prefix32.new 24 + # + # prefix.to_u32 + # #=> 4294967040 + # def to_u32 [bits].pack("B*").unpack("N").first end + # + # Shortcut for the octecs in the dotted decimal + # representation + # + # prefix = IPAddress::Prefix32.new 24 + # + # prefix[2] + # #=> 255 + # def [](index) octets[index] end + # + # The hostmask is the contrary of the subnet mask, + # as it shows the bits that can change within the + # hosts + # + # prefix = IPAddress::Prefix32.new 24 + # + # prefix.hostmask + # #=> "0.0.0.255" + # def hostmask [~to_u32].pack("N").unpack("CCCC").join(".") end + # + # Creates a new prefix by parsing a netmask in + # dotted decimal form + # + # prefix = IPAddress::Prefix32::parse_netmask "255.255.255.0" + # #=> 24 + # def self.parse_netmask(netmask) octets = netmask.split(".").map{|i| i.to_i} num = octets.pack("C"*octets.size).unpack("B*").first.count "1" @@ -84,6 +155,12 @@ module IPAddress class Prefix128 < Prefix + # + # Creates a new prefix object for 128 bits IPv6 addresses + # + # prefix = IPAddress::Prefix128.new 64 + # #=> 64 + # def initialize(num=128) unless (1..128).include? num.to_i raise ArgumentError, "Prefix must be in range 1..128, got: #{num}" @@ -91,10 +168,29 @@ module IPAddress super(num.to_i) end + # + # Transforms the prefix into a string of bits + # representing the netmask + # + # prefix = IPAddress::Prefix128.new 64 + # + # prefix.bits + # #=> "1111111111111111111111111111111111111111111111111111111111111111" + # "0000000000000000000000000000000000000000000000000000000000000000" + # def bits "1" * @prefix + "0" * (128 - @prefix) end + # + # Unsigned 128 bits decimal number representing + # the prefix + # + # prefix = IPAddress::Prefix128.new 64 + # + # prefix.to_u128 + # #=> 340282366920938463444927863358058659840 + # def to_u128 eval "0b#{bits}.to_i" end -- cgit v1.2.1