From 636f76a410b99d78867bbc8521e3dc5ae6263c8c Mon Sep 17 00:00:00 2001 From: Marco Ceresa Date: Thu, 20 May 2010 15:49:00 +0100 Subject: Completed most documentation on README.rdoc and ipv6.rb --- lib/ipaddress/ipv6.rb | 228 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 223 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/ipaddress/ipv6.rb b/lib/ipaddress/ipv6.rb index 45fdd07..3bcf65b 100644 --- a/lib/ipaddress/ipv6.rb +++ b/lib/ipaddress/ipv6.rb @@ -15,6 +15,49 @@ module IPAddress; # # Class IPAddress::IPv6 is used to handle IPv6 type addresses. # + # == IPv6 addresses + # + # IPv6 addresses are 128 bits long, in contrast with IPv4 addresses + # which are only 32 bits long. An IPv6 address is generally written as + # eight groups of four hexadecimal digits, each group representing 16 + # bits or two octect. For example, the following is a valid IPv6 + # address: + # + # 1080:0000:0000:0000:0008:0800:200c:417a + # + # Letters in an IPv6 address are usually written downcase, as per + # RFC. You can create a new IPv6 object using uppercase letters, but + # they will be converted. + # + # === Compression + # + # Since IPv6 addresses are very long to write, there are some + # semplifications and compressions that you can use to shorten them. + # + # * Leading zeroes: all the leading zeroes within a group can be + # omitted: "0008" would become "8" + # + # * A string of consecutive zeroes can be replaced by the string + # "::". This can be only applied once. + # + # Using compression, the IPv6 address written above can be shorten into + # the following, equivalent, address + # + # 1080::8:800:200c:417a + # + # This short version is often used in human representation. + # + # === Network Mask + # + # As we used to do with IPv4 addresses, an IPv6 address can be written + # using the prefix notation to specify the subnet mask: + # + # 1080::8:800:200c:417a/64 + # + # The /64 part means that the first 64 bits of the address are + # representing the network portion, and the last 64 bits are the host + # portion. + # # class IPv6 < IPBase @@ -410,16 +453,110 @@ module IPAddress; end # class IPv6 + # + # The address with all zero bits is called the +unspecified+ address + # (corresponding to 0.0.0.0 in IPv4). It should be something like this: + # + # 0000:0000:0000:0000:0000:0000:0000:0000 + # + # but, with the use of compression, it is usually written as just two + # colons: + # + # :: + # + # or, specifying the netmask: + # + # ::/128 + # + # With IPAddress, create a new unspecified IPv6 address using its own + # subclass: + # + # ip = IPAddress::IPv6::Unspecified.new + # + # ip.to_s + # #=> => "::/128" + # + # You can easily check if an IPv6 object is an unspecified address by + # using the IPv6#unspecified? method + # + # ip.unspecified? + # #=> true + # + # An unspecified IPv6 address can also be created with the wrapper + # method, like we've seen before + # + # ip = IPAddress "::" + # + # ip.unspecified? + # #=> true + # + # This address must never be assigned to an interface and is to be used + # only in software before the application has learned its host's source + # address appropriate for a pending connection. Routers must not forward + # packets with the unspecified address. + # class IPAddress::IPv6::Unspecified < IPAddress::IPv6 + # + # Creates a new IPv6 unspecified address + # + # ip = IPAddress::IPv6::Unspecified.new + # + # ip.to_s + # #=> => "::/128" + # def initialize @address = ("0000:"*8).chop @groups = Array.new(8,0) @prefix = Prefix128.new(128) @compressed = compress_address - end # class IPv6::Unspecified - end + end + end # class IPv6::Unspecified + # + # The loopback address is a unicast localhost address. If an + # application in a host sends packets to this address, the IPv6 stack + # will loop these packets back on the same virtual interface. + # + # Loopback addresses are expressed in the following form: + # + # ::1 + # + # or, with their appropriate prefix, + # + # ::1/128 + # + # As for the unspecified addresses, IPv6 loopbacks can be created with + # IPAddress calling their own class: + # + # ip = IPAddress::IPv6::Loopback.new + # + # ip.to_s + # #=> "::1/128" + # + # or by using the wrapper: + # + # ip = IPAddress "::1" + # + # ip.to_s + # #=> "::1/128" + # + # Checking if an address is loopback is easy with the IPv6#loopback? + # method: + # + # ip.loopback? + # #=> true + # + # The IPv6 loopback address corresponds to 127.0.0.1 in IPv4. + # class IPAddress::IPv6::Loopback < IPAddress::IPv6 + # + # Creates a new IPv6 unspecified address + # + # ip = IPAddress::IPv6::Loopback.new + # + # ip.to_s + # #=> "::1/128" + # def initialize @address = ("0000:"*7)+"0001" @groups = Array.new(7,0).push(1) @@ -428,27 +565,108 @@ module IPAddress; end end # class IPv6::Loopback + # + # It is usually identified as a IPv4 mapped IPv6 address, a particular + # IPv6 address which aids the transition from IPv4 to IPv6. The + # structure of the address is + # + # ::ffff:w.y.x.z + # + # where w.x.y.z is a normal IPv4 address. For example, the following is + # a mapped IPv6 address: + # + # ::ffff:192.168.100.1 + # + # IPAddress is very powerful in handling mapped IPv6 addresses, as the + # IPv4 portion is stored internally as a normal IPv4 object. Let's have + # a look at some examples. To create a new mapped address, just use the + # class builder itself + # + # ip6 = IPAddress::IPv6::Mapped.new "::ffff:172.16.10.1/128" + # + # or just use the wrapper method + # + # ip6 = IPAddress "::ffff:172.16.10.1/128" + # + # Let's check it's really a mapped address: + # + # ip6.mapped? + # #=> true + # + # ip6.to_s + # #=> "::FFFF:172.16.10.1/128" + # + # Now with the +ipv4+ attribute, we can easily access the IPv4 portion + # of the mapped IPv6 address: + # + # ip6.ipv4.address + # #=> "172.16.10.1" + # + # Internally, the IPv4 address is stored as two 16 bits + # groups. Therefore all the usual methods for an IPv6 address are + # working perfectly fine: + # + # ip6.to_hex + # #=> "00000000000000000000ffffac100a01" + # + # ip6.address + # #=> "0000:0000:0000:0000:0000:ffff:ac10:0a01" + # + # A mapped IPv6 can also be created just by specify the address in the + # following format: + # + # ip6 = IPAddress "::172.16.10.1" + # + # That is, two colons and the IPv4 address. However, as by RFC, the ffff + # group will be automatically added at the beginning + # + # ip6.to_s + # => "::ffff:172.16.10.1/128" + # + # making it a mapped IPv6 compatible address. + # class IPAddress::IPv6::Mapped < IPAddress::IPv6 + # Access the internal IPv4 address attr_reader :ipv4 + # + # Creates a new IPv6 unspecified address + # + # ip6 = IPAddress::IPv6::Mapped.new "::ffff:172.16.10.1/128" + # def initialize(str) string, netmask = str.split("/") @ipv4 = IPAddress::IPv4.extract(string) super("::ffff:#{@ipv4.to_ipv6}/#{netmask}") end + # + # Similar to IPv6#to_s, but prints out the IPv4 address + # in dotted decimal format + # + # + # ip6 = IPAddress "::ffff:172.16.10.1/128" + # + # ip6.to_s + # #=> "::FFFF:172.16.10.1/128" + # def to_s "::ffff:#{@ipv4.address}/#@prefix" end + # + # Checks if the IPv6 address is IPv4 mapped + # + # ip6 = IPAddress "::ffff:172.16.10.1/128" + # + # ip6.mapped? + # #=> true + # def mapped? true end - end # class IPv6::Mapped - - end # module IPAddress -- cgit v1.2.1