summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMarco Ceresa <ceresa@gmail.com>2010-05-20 15:49:00 +0100
committerMarco Ceresa <ceresa@gmail.com>2010-05-20 15:49:00 +0100
commit636f76a410b99d78867bbc8521e3dc5ae6263c8c (patch)
treeaefed6234b03e0abc02056c59d76bec9938bd0b9 /lib
parentfbe865911ad4e4c15c5baac719db0df20ef45b58 (diff)
downloadipaddress-636f76a410b99d78867bbc8521e3dc5ae6263c8c.tar.gz
Completed most documentation on README.rdoc and ipv6.rb
Diffstat (limited to 'lib')
-rw-r--r--lib/ipaddress/ipv6.rb228
1 files changed, 223 insertions, 5 deletions
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