ipaddress 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|