ipaddress 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +73 -0
- data/README.rdoc +120 -86
- data/Rakefile +7 -15
- data/VERSION +1 -1
- data/lib/ipaddress.rb +131 -15
- data/lib/ipaddress/extensions/extensions.rb +8 -2
- data/lib/ipaddress/ipv4.rb +132 -49
- data/lib/ipaddress/ipv6.rb +64 -18
- data/lib/ipaddress/prefix.rb +38 -1
- data/test/ipaddress/ipv4_test.rb +92 -38
- data/test/ipaddress/ipv6_test.rb +34 -10
- data/test/ipaddress/prefix_test.rb +15 -0
- data/test/ipaddress_test.rb +17 -0
- data/test/test_helper.rb +0 -5
- metadata +11 -25
- data/lib/ipaddress/ipbase.rb +0 -83
- data/test/ipaddress/ipbase_test.rb +0 -28
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
|
2
|
+
== ipaddress 0.6.0
|
3
|
+
|
4
|
+
=== API changes
|
5
|
+
* IPv4#to_s now returns the address portion only,
|
6
|
+
to retain compatibility with IPAddr. Example:
|
7
|
+
|
8
|
+
IPAddress("172.16.10.1/24").to_s
|
9
|
+
#=> "172.16.10.1" # ipaddress 0.6.0
|
10
|
+
|
11
|
+
IPAddress("172.16.10.1/24").to_s
|
12
|
+
#=> "172.16.10.1/24" # ipaddress 0.5.0
|
13
|
+
|
14
|
+
* IPv6#to_s now returns the address portion only,
|
15
|
+
to retain compatibility with IPAddr. Example:
|
16
|
+
|
17
|
+
IPAddress "2001:db8::8:800:200c:417a/64".to_s
|
18
|
+
#=> "2001:db8::8:800:200c:417a" # ipaddress 0.6.0
|
19
|
+
|
20
|
+
IPAddress "2001:db8::8:800:200c:417a/64".to_s
|
21
|
+
#=> "2001:db8::8:800:200c:417a/64" # ipaddress 0.6.0
|
22
|
+
|
23
|
+
* IPv6::Unspecified#to_s, IPv6::Loopback and
|
24
|
+
IPv6::Mapped#to_s now return the address portion only,
|
25
|
+
to retain compatibility with IPAddr.
|
26
|
+
* IPv4::summarize now returns an array even if the
|
27
|
+
result is a single subnet, to keep consistency
|
28
|
+
and avoid confusion
|
29
|
+
|
30
|
+
=== New methods
|
31
|
+
* IPv4#to_string and IPv6#to_string: print the address
|
32
|
+
with the prefix portion, like the #to_s method in
|
33
|
+
ipaddress 0.5.0
|
34
|
+
* IPAddress::parse, for those who don't like the wrapper
|
35
|
+
method IPAddress()
|
36
|
+
* IPv6#to_string_uncompressed, returns a string with the
|
37
|
+
uncompressed IPv6 and the prefix
|
38
|
+
* IPv6::Mapped#to_string, returns the IPv6 Mapped address
|
39
|
+
with IPv4 notation and the prefix
|
40
|
+
* IPv6#reverse, returns the ip6.arpa DNS reverse lookup
|
41
|
+
string
|
42
|
+
* IPv4#arpa and IPv6#arpa, alias of the respective #reverse
|
43
|
+
methods
|
44
|
+
* Prefix#+, Prefix#-
|
45
|
+
|
46
|
+
=== Library structure
|
47
|
+
* Moved all the IPAddress module methods from
|
48
|
+
lib/ipaddress/ipbase.rb to lib/ipaddress.rb
|
49
|
+
* Removed IPBase superclass
|
50
|
+
* IPv4 and IPv6 classes no longer inherit from IPBase
|
51
|
+
* Removed lib/ipaddress/ipbase.rb
|
52
|
+
* Removed test/ipaddress/ipbase_test.rb
|
53
|
+
|
54
|
+
=== Minor fixes
|
55
|
+
* Replaced Ruby 1.9 deprecated Hash#index with Hash#key
|
56
|
+
* Removed require ruby-prof from tests which was causing
|
57
|
+
users to install ruby-prof or manually remove the line
|
58
|
+
* Removed "must" method from tests, replaced by normal
|
59
|
+
Test::Unit methods
|
60
|
+
* Removed duplicate Jeweler entry in Rakefile
|
61
|
+
* Made Integer#closest_power_of_2 more general by adding
|
62
|
+
an optional limit parameter
|
63
|
+
* Fixed summarization algorithm (thanks to nicolas fevrier)
|
64
|
+
* Fixed bug in prefix_from_ip (thanks to jdpace)
|
65
|
+
|
66
|
+
=== Documentation
|
67
|
+
* Normalized README rdoc headers
|
68
|
+
* Added documentation for IPAddress::Prefix
|
69
|
+
* Added documentation for IPAddress::IPv4 and
|
70
|
+
IPAddress::IPv6
|
71
|
+
* Fixed formatting
|
72
|
+
* Fixed lots of typos
|
73
|
+
|
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= IPAddress
|
2
2
|
|
3
3
|
IPAddress is a Ruby library designed to make the use of IPv4 and IPv6
|
4
|
-
addresses
|
4
|
+
addresses simple, powerful and enjoyable. It provides a complete set of
|
5
5
|
methods to handle IP addresses for any need, from simple scripting to
|
6
6
|
full network design.
|
7
7
|
|
@@ -12,7 +12,25 @@ let you start being productive immediately.
|
|
12
12
|
This document provides a brief introduction to the library and
|
13
13
|
examples of typical usage.
|
14
14
|
|
15
|
-
|
15
|
+
== Requirements
|
16
|
+
|
17
|
+
* Ruby >= 1.8.6 (not tested with previous versions)
|
18
|
+
|
19
|
+
IPAddress works perfectly on:
|
20
|
+
|
21
|
+
* Ruby 1.8.6 (2007-03-13 patchlevel 0)
|
22
|
+
* Ruby 1.8.7
|
23
|
+
* Ruby 1.9.1
|
24
|
+
* Ruby 1.9.2dev (2010-06-08 revision 28230)
|
25
|
+
* Ruby 1.9.2dev (2010-07-15 revision 28653)
|
26
|
+
* Rubinius 1.0.1 (1.8.7 release 2010-06-03 JI)
|
27
|
+
* Ironruby >= 1.0
|
28
|
+
|
29
|
+
It hasn't yet been tested on any other platform, so if you want to collaborate feel
|
30
|
+
free to send a small report to my email address, or
|
31
|
+
{join the discussion}[http://groups.google.com/group/ruby-ipaddress].
|
32
|
+
|
33
|
+
== Why not using IPAddr?
|
16
34
|
|
17
35
|
IPAddr is the IP addresses library that comes with Ruby standard
|
18
36
|
lib. We found this library, although very well written, not very
|
@@ -25,10 +43,13 @@ Some quick examples of things you can't do with IPAddr:
|
|
25
43
|
* iterate over hosts
|
26
44
|
* perform subnetting or network aggregation
|
27
45
|
|
46
|
+
Moreover, many methods and procedures are so old that they have been
|
47
|
+
declared deprecated by the IETF.
|
48
|
+
|
28
49
|
We hope that IPAddress will address all these issues and meet all your
|
29
50
|
needs in network programming.
|
30
51
|
|
31
|
-
|
52
|
+
== Installation
|
32
53
|
|
33
54
|
Install the library using rubygems
|
34
55
|
|
@@ -41,36 +62,35 @@ You can then use it in your programs:
|
|
41
62
|
|
42
63
|
Another way would be to clone the git repository
|
43
64
|
|
44
|
-
$ git clone git://github.com/bluemonk/
|
65
|
+
$ git clone git://github.com/bluemonk/ipaddress.git
|
45
66
|
|
46
67
|
And then install the library
|
47
68
|
|
48
69
|
$ cd ipaddress
|
49
70
|
ipaddress$ rake install
|
50
71
|
|
51
|
-
|
72
|
+
== Documentation
|
52
73
|
|
53
74
|
The code is fully documented with RDoc. You can generate the
|
54
75
|
documentation with Rake:
|
55
76
|
|
56
77
|
ipaddress$ rake rdoc
|
57
78
|
|
58
|
-
The latest documentation can be found online at
|
59
|
-
|
60
|
-
http://marcoceresa.com/ipaddress
|
79
|
+
The latest documentation can be found online at
|
80
|
+
{this address}[http://marcoceresa.com/ipaddress]
|
61
81
|
|
62
|
-
|
82
|
+
== Usage
|
63
83
|
|
64
84
|
In this section I will illustrate how to use the IPAddress library
|
65
85
|
through some examples of common tasks.
|
66
86
|
|
67
|
-
|
87
|
+
=== IPv4
|
68
88
|
|
69
89
|
Class IPAddress::IPv4 is used to handle IPv4 type addresses. IPAddress
|
70
90
|
is similar to other IP Addresses libraries, like Ruby's own
|
71
91
|
IPAddr. However it works slightly different, as we will see.
|
72
92
|
|
73
|
-
|
93
|
+
==== Create a new IPv4 address
|
74
94
|
|
75
95
|
The usual way to express an IP Address is using its dotted decimal
|
76
96
|
form, such as 172.16.10.1, and a prefix, such as 24, separated by a
|
@@ -94,7 +114,7 @@ You can specify an IPv4 address in any of two ways:
|
|
94
114
|
In this example, prefix /24 and netmask 255.255.255.0 are the same and
|
95
115
|
you have the flexibility to use either one of them.
|
96
116
|
|
97
|
-
|
117
|
+
==== Classful networks
|
98
118
|
|
99
119
|
If you don't specify a prefix (or a subnet mask), then the library
|
100
120
|
will create an object base on the CLASSFUL network from the given
|
@@ -124,10 +144,10 @@ You can easily check which CLASSFUL network the IP belongs:
|
|
124
144
|
These methods are only checking the address portion of an IP, and are
|
125
145
|
indipendent from its prefix.
|
126
146
|
|
127
|
-
For more information on CLASSFUL networks visit the
|
128
|
-
Wikipedia page
|
147
|
+
For more information on CLASSFUL networks visit the
|
148
|
+
{Wikipedia page}[http://en.wikipedia.org/wiki/Classful_network]
|
129
149
|
|
130
|
-
|
150
|
+
==== Handling the IPv4 address
|
131
151
|
|
132
152
|
Once created, you can obtain the attributes for an IPv4 object:
|
133
153
|
|
@@ -157,28 +177,30 @@ range:
|
|
157
177
|
#=> 16
|
158
178
|
|
159
179
|
If you need to print out the IPv4 address in a canonical form, you can
|
160
|
-
use IPv4#
|
180
|
+
use IPv4#to_string
|
161
181
|
|
162
|
-
ip.
|
182
|
+
ip.to_string
|
163
183
|
#=> "172.16.10.l/24"
|
164
184
|
|
165
|
-
|
185
|
+
==== Changing netmask
|
166
186
|
|
167
187
|
You can set a new prefix (netmask) after creating an IPv4
|
168
188
|
object. For example:
|
169
189
|
|
170
190
|
ip.prefix = 25
|
171
|
-
|
191
|
+
|
192
|
+
ip.to_string
|
172
193
|
#=> "172.16.10.l/25"
|
173
194
|
|
174
195
|
If you need to use a netmask in IPv4 format, you can achive so by
|
175
196
|
using the IPv4#netmask= method
|
176
197
|
|
177
198
|
ip.netmask = "255.255.255.252"
|
178
|
-
|
199
|
+
|
200
|
+
ip.to_string
|
179
201
|
#=> "172.16.10.1/30"
|
180
202
|
|
181
|
-
|
203
|
+
==== Working with networks, broadcasts and addresses
|
182
204
|
|
183
205
|
Some very important topics in dealing with IP addresses are the
|
184
206
|
concepts of +network+ and +broadcast+, as well as the addresses
|
@@ -199,15 +221,18 @@ This is very important because, for instance, IP "172.16.10.1/16" is
|
|
199
221
|
very different to the previous one, belonging to the very different
|
200
222
|
network "172.16.0.0/16".
|
201
223
|
|
224
|
+
===== Networks
|
225
|
+
|
202
226
|
With IPAddress it's very easy to calculate the network for an IP
|
203
227
|
address:
|
204
228
|
|
205
229
|
ip = IPAddress "172.16.10.1/24"
|
230
|
+
|
206
231
|
net = ip.network
|
207
232
|
#=> #<IPAddress::IPv4:0xb7a5ab24 @octets=[172, 16, 10, 0],
|
208
233
|
@prefix=24,
|
209
234
|
@address="172.16.10.0">
|
210
|
-
net.
|
235
|
+
net.to_string
|
211
236
|
#=> "172.16.10.0/24"
|
212
237
|
|
213
238
|
The IPv4#network method creates a new IPv4 object from the network
|
@@ -226,6 +251,8 @@ network or not:
|
|
226
251
|
ip2.network?
|
227
252
|
#=> true
|
228
253
|
|
254
|
+
===== Broadcast
|
255
|
+
|
229
256
|
The broadcast address is the contrary than the network number: where
|
230
257
|
the network number has all zeroes in the host portion, the broadcast
|
231
258
|
address has all one's. For example, ip "172.16.10.1/24" has broadcast
|
@@ -237,13 +264,16 @@ counterpart: it creates a new IPv4 object to handle the broadcast
|
|
237
264
|
address:
|
238
265
|
|
239
266
|
ip = IPAddress "172.16.10.1/24"
|
267
|
+
|
240
268
|
bcast = ip.broadcast
|
241
269
|
#=> #<IPAddress::IPv4:0xb7a406fc @octets=[172, 16, 10, 255],
|
242
270
|
@prefix=24,
|
243
271
|
@address="172.16.10.255">
|
244
|
-
bcast.
|
272
|
+
bcast.to_string
|
245
273
|
#=> "172.16.10.255/24"
|
246
274
|
|
275
|
+
===== Addresses, ranges and iterators
|
276
|
+
|
247
277
|
So we see that the netmask essentially specifies a range for IP
|
248
278
|
addresses that are included in a network: all the addresses between
|
249
279
|
the network number and the broadcast. IPAddress has many methods to
|
@@ -274,13 +304,13 @@ respectively the first and the last host address in the range
|
|
274
304
|
|
275
305
|
ip = IPAddress "172.16.10.100/24"
|
276
306
|
|
277
|
-
ip.first.
|
307
|
+
ip.first.to_string
|
278
308
|
#=> "172.16.10.1/24"
|
279
309
|
|
280
|
-
ip.last.
|
310
|
+
ip.last.to_string
|
281
311
|
#=> "172.16.10.254/24"
|
282
312
|
|
283
|
-
|
313
|
+
==== IP special formats
|
284
314
|
|
285
315
|
The IPAddress library provides a complete set of methods to access an
|
286
316
|
IPv4 address in special formats, such as binary, 32 bits unsigned int,
|
@@ -289,6 +319,7 @@ data and hexadecimal.
|
|
289
319
|
Let's take the following IPv4 as an example:
|
290
320
|
|
291
321
|
ip = IPAddress "172.16.10.1/24"
|
322
|
+
|
292
323
|
ip.address
|
293
324
|
#=> "172.16.10.1"
|
294
325
|
|
@@ -322,12 +353,12 @@ suitable to use in IPv4-IPv6 mapped addresses:
|
|
322
353
|
#=> "ac10:0a01"
|
323
354
|
|
324
355
|
|
325
|
-
|
356
|
+
=== Network design with IPAddress
|
326
357
|
|
327
358
|
IPAddress includes a lot of useful methods to manipulate IPv4 and IPv6
|
328
359
|
networks and do some basic network design.
|
329
360
|
|
330
|
-
|
361
|
+
==== Subnetting
|
331
362
|
|
332
363
|
The process of subnetting is the division of a network into smaller
|
333
364
|
(in terms of hosts capacity) networks, called subnets, so that they
|
@@ -347,7 +378,7 @@ Subnetting is easy with IPAddress. Let's work out the last example:
|
|
347
378
|
#<IPAddress::IPv4:0xb7b0e5ac @octets=[172,16,10,128] [...]
|
348
379
|
#<IPAddress::IPv4:0xb7b0e0c0 @octets=[172,16,10,192] [...]]
|
349
380
|
|
350
|
-
subnets.map{|i| i.
|
381
|
+
subnets.map{|i| i.to_string}
|
351
382
|
#=> ["172.16.10.0/26", "172.16.10.64/26", "172.16.10.128/26",
|
352
383
|
"172.16.10.192/26"]
|
353
384
|
|
@@ -359,7 +390,7 @@ example:
|
|
359
390
|
|
360
391
|
ip = IPAddress("172.16.10.58/24")
|
361
392
|
|
362
|
-
ip.subnet(4).map{|i| i.
|
393
|
+
ip.subnet(4).map{|i| i.to_string}
|
363
394
|
#=> ["172.16.10.0/26", "172.16.10.64/26", "172.16.10.128/26",
|
364
395
|
"172.16.10.192/26"]
|
365
396
|
|
@@ -368,7 +399,7 @@ which is a power of two: in this way, you can be sure that the network
|
|
368
399
|
will be divived evenly, and all the subnets will have the same number
|
369
400
|
of hosts.
|
370
401
|
|
371
|
-
|
402
|
+
==== Uneven subnetting
|
372
403
|
|
373
404
|
IPAddress also handles un-even subnetting: if you specify any number
|
374
405
|
(up to the prefix limit), the network will be divided so that the
|
@@ -378,7 +409,8 @@ fill out the space.
|
|
378
409
|
As an example, let's divide network 172.16.10.0/24 into 3 different subnets:
|
379
410
|
|
380
411
|
network = IPAddress("172.16.10.0/24")
|
381
|
-
|
412
|
+
|
413
|
+
network.subnet(3).map{|i| i.to_string}
|
382
414
|
#=> ["172.16.10.0/26",
|
383
415
|
"172.16.10.64/26",
|
384
416
|
"172.16.10.128/25"]
|
@@ -386,7 +418,8 @@ As an example, let's divide network 172.16.10.0/24 into 3 different subnets:
|
|
386
418
|
We can go even further and divide into 11 subnets:
|
387
419
|
|
388
420
|
network = IPAddress("172.16.10.0/24")
|
389
|
-
|
421
|
+
|
422
|
+
network.subnet(11).map{|i| i.to_string}
|
390
423
|
#=> ["172.16.10.0/28", "172.16.10.16/28", "172.16.10.32/28",
|
391
424
|
"172.16.10.48/28", "172.16.10.64/28", "172.16.10.80/28",
|
392
425
|
"172.16.10.96/28", "172.16.10.112/28", "172.16.10.128/27",
|
@@ -395,7 +428,7 @@ We can go even further and divide into 11 subnets:
|
|
395
428
|
As you can see, most of the networks are /28, with a few /27 and one
|
396
429
|
/26 to fill up the remaning space.
|
397
430
|
|
398
|
-
|
431
|
+
==== Summarization
|
399
432
|
|
400
433
|
Summarization (or aggregation) is the process when two or more
|
401
434
|
networks are taken together to check if a supernet, including
|
@@ -406,10 +439,11 @@ occur if there are no holes in the aggregated network, or, in
|
|
406
439
|
other words, if the given networks fill completely the address space
|
407
440
|
of the supernet. So the two rules are:
|
408
441
|
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
442
|
+
1) The aggregate network must contain +all+ the IP addresses of the
|
443
|
+
original networks;
|
444
|
+
|
445
|
+
2) The aggregate network must contain +only+ the IP addresses of the
|
446
|
+
original networks;
|
413
447
|
|
414
448
|
A few examples will help clarify the above. Let's consider for
|
415
449
|
instance the following two networks:
|
@@ -420,7 +454,7 @@ instance the following two networks:
|
|
420
454
|
These two networks can be expressed using only one IP address
|
421
455
|
network if we change the prefix. Let Ruby do the work:
|
422
456
|
|
423
|
-
IPAddress::IPv4::summarize(ip1,ip2).
|
457
|
+
IPAddress::IPv4::summarize(ip1,ip2).to_string
|
424
458
|
#=> "172.16.10.0/23"
|
425
459
|
|
426
460
|
We note how the network "172.16.10.0/23" includes all the
|
@@ -447,8 +481,8 @@ aggregated in a single /22:
|
|
447
481
|
ip3 = IPAddress("10.0.2.1/24")
|
448
482
|
ip4 = IPAddress("10.0.3.1/24")
|
449
483
|
|
450
|
-
IPAddress::IPv4::summarize(ip1,ip2,ip3,ip4).
|
451
|
-
#=> "10.0.0.0/22"
|
484
|
+
IPAddress::IPv4::summarize(ip1,ip2,ip3,ip4).map{|i| i.to_string}
|
485
|
+
#=> ["10.0.0.0/22"]
|
452
486
|
|
453
487
|
But the following networks can't be summarized in a single
|
454
488
|
network:
|
@@ -457,13 +491,14 @@ network:
|
|
457
491
|
ip2 = IPAddress("10.0.2.1/24")
|
458
492
|
ip3 = IPAddress("10.0.3.1/24")
|
459
493
|
ip4 = IPAddress("10.0.4.1/24")
|
460
|
-
|
494
|
+
|
495
|
+
IPAddress::IPv4::summarize(ip1,ip2,ip3,ip4).map{|i| i.to_string}
|
461
496
|
#=> ["10.0.1.0/24","10.0.2.0/23","10.0.4.0/24"]
|
462
497
|
|
463
498
|
In this case, the two summarizables networks have been aggregated into
|
464
499
|
a single /23, while the other two networks have been left untouched.
|
465
500
|
|
466
|
-
|
501
|
+
==== Supernetting
|
467
502
|
|
468
503
|
Supernetting is a different operation than aggregation, as it only
|
469
504
|
works on a single network and returns a new single IPv4 object,
|
@@ -477,26 +512,25 @@ example, given the network
|
|
477
512
|
|
478
513
|
you can supernet it with a new /23 prefix
|
479
514
|
|
480
|
-
ip.supernet(23).
|
515
|
+
ip.supernet(23).to_string
|
481
516
|
#=> "172.16.10.0/23"
|
482
517
|
|
483
518
|
However if you supernet it with a /22 prefix, the network address will
|
484
519
|
change:
|
485
520
|
|
486
|
-
ip.supernet(22).
|
521
|
+
ip.supernet(22).to_string
|
487
522
|
#=> "172.16.8.0/22"
|
488
523
|
|
489
524
|
This is because "172.16.10.0/22" is not a network anymore, but an host
|
490
525
|
address.
|
491
526
|
|
492
|
-
|
493
|
-
=IPv6
|
527
|
+
== IPv6
|
494
528
|
|
495
529
|
IPAddress is not only fantastic for IPv4 addresses, it's also great to
|
496
530
|
handle IPv6 addresses family! Let's discover together how to use it in
|
497
531
|
our projects.
|
498
532
|
|
499
|
-
|
533
|
+
=== IPv6 addresses
|
500
534
|
|
501
535
|
IPv6 addresses are 128 bits long, in contrast with IPv4 addresses
|
502
536
|
which are only 32 bits long. An IPv6 address is generally written as
|
@@ -510,7 +544,7 @@ Letters in an IPv6 address are usually written downcase, as per
|
|
510
544
|
RFC. You can create a new IPv6 object using uppercase letters, but
|
511
545
|
they will be converted.
|
512
546
|
|
513
|
-
|
547
|
+
==== Compression
|
514
548
|
|
515
549
|
Since IPv6 addresses are very long to write, there are some
|
516
550
|
semplifications and compressions that you can use to shorten them.
|
@@ -528,7 +562,7 @@ the following, equivalent, address
|
|
528
562
|
|
529
563
|
This short version is often used in human representation.
|
530
564
|
|
531
|
-
|
565
|
+
==== Network Mask
|
532
566
|
|
533
567
|
As we used to do with IPv4 addresses, an IPv6 address can be written
|
534
568
|
using the prefix notation to specify the subnet mask:
|
@@ -539,7 +573,7 @@ The /64 part means that the first 64 bits of the address are
|
|
539
573
|
representing the network portion, and the last 64 bits are the host
|
540
574
|
portion.
|
541
575
|
|
542
|
-
|
576
|
+
=== Using IPAddress with IPv6 addresses
|
543
577
|
|
544
578
|
All the IPv6 representations we've just seen are perfectly fine when
|
545
579
|
you want to create a new IPv6 address:
|
@@ -576,7 +610,7 @@ IPv6#compressed method:
|
|
576
610
|
ip6.compressed
|
577
611
|
#=> "2001:db8::8:800:200c:417a"
|
578
612
|
|
579
|
-
|
613
|
+
=== Handling the IPv6 address
|
580
614
|
|
581
615
|
Accessing the groups that form an IPv6 address is very easy with the
|
582
616
|
IPv6#groups method:
|
@@ -616,21 +650,21 @@ or to hexadecimal representation
|
|
616
650
|
ip6.to_hex
|
617
651
|
#=> "20010db80000000000080800200c417a"
|
618
652
|
|
619
|
-
To print out an IPv6 address in human readable form, use the IPv6#to_s
|
620
|
-
and IPv6#
|
653
|
+
To print out an IPv6 address in human readable form, use the IPv6#to_s, IPv6#to_string
|
654
|
+
and IPv6#to_string_uncompressed methods
|
621
655
|
|
622
656
|
ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
|
623
657
|
|
624
|
-
ip6.
|
658
|
+
ip6.to_string
|
625
659
|
#=> "2001:db8::8:800:200c:417a/96"
|
626
660
|
|
627
|
-
ip6.
|
661
|
+
ip6.to_string_uncompressed
|
628
662
|
#=> "2001:0db8:0000:0000:0008:0800:200c:417a/96"
|
629
663
|
|
630
|
-
As you can see, IPv6.
|
631
|
-
IPv6.
|
664
|
+
As you can see, IPv6.to_string prints out the compressed form, while
|
665
|
+
IPv6.to_string_uncompressed uses the expanded version.
|
632
666
|
|
633
|
-
|
667
|
+
==== Compressing and uncompressing
|
634
668
|
|
635
669
|
If you have a string representing an IPv6 address, you can easily
|
636
670
|
compress it and uncompress it using the two class methods IPv6::expand
|
@@ -657,7 +691,7 @@ These methods can be used when you don't want to create a new object
|
|
657
691
|
just for expanding or compressing an address (although a new object is
|
658
692
|
actually created internally).
|
659
693
|
|
660
|
-
|
694
|
+
=== New IPv6 address from other formats
|
661
695
|
|
662
696
|
You can create a new IPv6 address from different formats than just a
|
663
697
|
string representing the colon-hex groups.
|
@@ -670,7 +704,7 @@ like in the following example:
|
|
670
704
|
ip6 = IPAddress::IPv6::parse_data data
|
671
705
|
ip6.prefix = 64
|
672
706
|
|
673
|
-
ip6.
|
707
|
+
ip6.to_string
|
674
708
|
#=> "2001:db8::8:800:200c:417a/64"
|
675
709
|
|
676
710
|
A new IPv6 address can also be created from an unsigned 128 bits
|
@@ -681,7 +715,7 @@ integer:
|
|
681
715
|
ip6 = IPAddress::IPv6::parse_u128 u128
|
682
716
|
ip6.prefix = 64
|
683
717
|
|
684
|
-
ip6.
|
718
|
+
ip6.to_string
|
685
719
|
#=> "1080::8:800:200c:417a/64"
|
686
720
|
|
687
721
|
Finally, a new IPv6 address can be created from an hex string:
|
@@ -691,16 +725,16 @@ Finally, a new IPv6 address can be created from an hex string:
|
|
691
725
|
ip6 = IPAddress::IPv6::parse_hex hex
|
692
726
|
ip6.prefix = 64
|
693
727
|
|
694
|
-
ip6.
|
728
|
+
ip6.to_string
|
695
729
|
#=> "2001:db8::8:800:200c:417a/64"
|
696
730
|
|
697
|
-
|
731
|
+
=== Special IPv6 addresses
|
698
732
|
|
699
733
|
Some IPv6 have a special meaning and are expressed in a special form,
|
700
734
|
quite different than an usual IPv6 address. IPAddress has builtin
|
701
735
|
support for unspecified, loopback and mapped IPv6 addresses.
|
702
736
|
|
703
|
-
|
737
|
+
==== Unspecified address
|
704
738
|
|
705
739
|
The address with all zero bits is called the +unspecified+ address
|
706
740
|
(corresponding to 0.0.0.0 in IPv4). It should be something like this:
|
@@ -721,8 +755,8 @@ subclass:
|
|
721
755
|
|
722
756
|
ip = IPAddress::IPv6::Unspecified.new
|
723
757
|
|
724
|
-
ip.
|
725
|
-
#=>
|
758
|
+
ip.to_string
|
759
|
+
#=> "::/128"
|
726
760
|
|
727
761
|
You can easily check if an IPv6 object is an unspecified address by
|
728
762
|
using the IPv6#unspecified? method
|
@@ -743,7 +777,7 @@ only in software before the application has learned its host's source
|
|
743
777
|
address appropriate for a pending connection. Routers must not forward
|
744
778
|
packets with the unspecified address.
|
745
779
|
|
746
|
-
|
780
|
+
==== Loopback address
|
747
781
|
|
748
782
|
The loopback address is a unicast localhost address. If an
|
749
783
|
application in a host sends packets to this address, the IPv6 stack
|
@@ -762,14 +796,14 @@ IPAddress calling their own class:
|
|
762
796
|
|
763
797
|
ip = IPAddress::IPv6::Loopback.new
|
764
798
|
|
765
|
-
ip.
|
799
|
+
ip.to_string
|
766
800
|
#=> "::1/128"
|
767
801
|
|
768
802
|
or by using the wrapper:
|
769
803
|
|
770
804
|
ip = IPAddress "::1"
|
771
805
|
|
772
|
-
ip.
|
806
|
+
ip.to_string
|
773
807
|
#=> "::1/128"
|
774
808
|
|
775
809
|
Checking if an address is loopback is easy with the IPv6#loopback?
|
@@ -780,7 +814,7 @@ method:
|
|
780
814
|
|
781
815
|
The IPv6 loopback address corresponds to 127.0.0.1 in IPv4.
|
782
816
|
|
783
|
-
|
817
|
+
==== Mapped address
|
784
818
|
|
785
819
|
It is usually identified as a IPv4 mapped IPv6 address, a particular
|
786
820
|
IPv6 address which aids the transition from IPv4 to IPv6. The
|
@@ -809,8 +843,8 @@ Let's check it's really a mapped address:
|
|
809
843
|
ip6.mapped?
|
810
844
|
#=> true
|
811
845
|
|
812
|
-
ip6.
|
813
|
-
#=> "::
|
846
|
+
ip6.to_string
|
847
|
+
#=> "::ffff:172.16.10.1/128"
|
814
848
|
|
815
849
|
Now with the +ipv4+ attribute, we can easily access the IPv4 portion
|
816
850
|
of the mapped IPv6 address:
|
@@ -836,29 +870,29 @@ following format:
|
|
836
870
|
That is, two colons and the IPv4 address. However, as by RFC, the ffff
|
837
871
|
group will be automatically added at the beginning
|
838
872
|
|
839
|
-
ip6.
|
873
|
+
ip6.to_string
|
840
874
|
=> "::ffff:172.16.10.1/128"
|
841
875
|
|
842
876
|
making it a mapped IPv6 compatible address.
|
843
877
|
|
844
|
-
|
878
|
+
== Community
|
845
879
|
|
846
|
-
|
880
|
+
Want to join the community?
|
847
881
|
|
848
|
-
*
|
849
|
-
* network design methods for IPv6
|
850
|
-
* parameter to IPv4#subnet to select where to fill the space
|
851
|
-
(beginning or ending)
|
852
|
-
* method to check if a network is private
|
882
|
+
* {IPAddress google group}[http://groups.google.com/group/ruby-ipaddress]
|
853
883
|
|
854
|
-
|
884
|
+
We've created a group to discuss about
|
885
|
+
IPAddress future development, features and provide some kind of support.
|
886
|
+
Feel free to join us and tell us what you think!
|
855
887
|
|
856
|
-
|
888
|
+
== Thanks to
|
857
889
|
|
858
|
-
Thanks to Luca Russo (vargolo)
|
859
|
-
review.
|
890
|
+
Thanks to Luca Russo (vargolo) and Simone Carletti (weppos) for all
|
891
|
+
the support and technical review. Thanks to Marco Beri, Bryan T. Richardson,
|
892
|
+
Nicolas Fevrier, jdpace, Daniele Alessandri and Steve Rawlinson for
|
893
|
+
their support, feedback and bug reports.
|
860
894
|
|
861
|
-
|
895
|
+
== Copyright
|
862
896
|
|
863
897
|
Copyright (c) 2009-2010 Marco Ceresa. See LICENSE for details.
|
864
898
|
|