ipaddress_2 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,964 @@
1
+ = IPAddress
2
+
3
+ IPAddress is a Ruby library designed to make the use of IPv4 and IPv6
4
+ addresses simple, powerful and enjoyable. It provides a complete set of
5
+ methods to handle IP addresses for any need, from simple scripting to
6
+ full network design.
7
+
8
+ IPAddress is written with a full OO interface, and its code is easy to
9
+ read, maintain and extend. The documentation is full of examples, to
10
+ let you start being productive immediately.
11
+
12
+ This document provides a brief introduction to the library and
13
+ examples of typical usage.
14
+
15
+ == Requirements
16
+
17
+ * Ruby 1.9.3 or later
18
+
19
+ Please refer to {Travis CI}[https://travis-ci.org/ipaddress2-gem/ipaddress2] for Build Tests on specific versions of Ruby.
20
+
21
+ {<img src="https://travis-ci.org/ipaddress2-gem/ipaddress2.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/ipaddress2-gem/ipaddress2] {<img src="https://codeclimate.com/github/ipaddress2-gem/ipaddress2/badges/gpa.svg" />}[https://codeclimate.com/github/ipaddress2-gem/ipaddress2]
22
+
23
+ If you want to contribute, please refer to {Contributing.md}[https://github.com/ipaddress2-gem/ipaddress2/blob/master/CONTRIBUTING.md].
24
+
25
+
26
+ == Installation
27
+
28
+ Install the library using rubygems
29
+
30
+ $ gem install ipaddress_2
31
+
32
+ You can then use it in your programs:
33
+
34
+ require 'ipaddress_2'
35
+
36
+ == Documentation
37
+
38
+ The code is fully documented with RDoc. You can generate the
39
+ documentation with Rake:
40
+
41
+ ipaddress$ rake rdoc
42
+
43
+ The latest documentation can be found online at
44
+ {this address}[http://www.rubydoc.info/gems/ipaddress_2/0.9.0]
45
+
46
+ == IPv4
47
+
48
+ Class `IPAddress::IPv4` is used to handle IPv4 type addresses. IPAddress
49
+ is similar to other IP Addresses libraries, like Ruby's own
50
+ IPAddr. However it works slightly different, as we will see.
51
+
52
+ === Create a new IPv4 address
53
+
54
+ The usual way to express an IP Address is using its dotted decimal
55
+ form, such as `172.16.10.1`, and a prefix, such as `24`, separated by a
56
+ slash.
57
+
58
+ 172.16.10.1/24
59
+
60
+ To create a new IPv4 object, you can use IPv4 own class
61
+
62
+ ip = IPAddress::IPv4.new "172.16.10.1/24"
63
+
64
+ or, in a easier way, using the IPAddress parse method
65
+
66
+ ip = IPAddress.parse "172.16.10.1/24"
67
+
68
+ which accepts and parses any kind of IP (uint32, IPv4, IPV6 and
69
+ IPv4 IPv6 Mapped addresses).
70
+
71
+ If you like syntactic sugar, you can use the wrapper method
72
+ `IPAddress()`, which is built around `IPAddress::parse`:
73
+
74
+ ip = IPAddress "172.16.10.1/24"
75
+
76
+ You can specify an IPv4 address in any of two ways:
77
+
78
+ IPAddress "172.16.10.1/24"
79
+ IPAddress "172.16.10.1/255.255.255.0"
80
+
81
+ In this example, prefix `/24` and netmask `255.255.255.0` are the same and
82
+ you have the flexibility to use either one of them.
83
+
84
+ If you don't explicitly specify the prefix (or the subnet mask),
85
+ IPAddress thinks you're dealing with host addresses and not with
86
+ networks. Therefore, the default prefix will be `/32`, or
87
+ `255.255.255.255`. For example:
88
+
89
+ # let's declare an host address
90
+ host = IPAddress::IPv4.new "10.1.1.1"
91
+
92
+ puts host.to_string
93
+ #=> "10.1.1.1/32"
94
+
95
+ The new created object has prefix `/32`, which is the same
96
+ as we created the following:
97
+
98
+ host = IPAddress::IPv4.new "10.1.1.1/32"
99
+
100
+ You can also pass a `uint32` to obtain an `IPAddress::IPv4` object:
101
+
102
+ # Create host object
103
+ ip = IPAddress 167837953
104
+ puts ip.to_string
105
+ #=> "10.1.1.1/32"
106
+
107
+ === Handling the IPv4 address
108
+
109
+ Once created, you can obtain the attributes for an IPv4 object:
110
+
111
+ ip = IPAddress("172.16.10.1/24")
112
+
113
+ ip.address
114
+ #=> "172.16.10.1"
115
+ ip.prefix
116
+ #=> 24
117
+
118
+ In case you need to retrieve the netmask in IPv4 format, you can use
119
+ the `IPv4#netmask` method:
120
+
121
+ ip.netmask
122
+ #=> "255.255.255.0"
123
+
124
+ A special attribute, `IPv4#octets`, is available to get the four
125
+ decimal octets from the IP address:
126
+
127
+ ip.octets
128
+ #=> [172,16,10,1]
129
+
130
+ Shortcut method `IPv4#[]`, provides access to a given octet whithin the
131
+ range:
132
+
133
+ ip[1]
134
+ #=> 16
135
+
136
+ If you need to print out the IPv4 address in a canonical form, you can
137
+ use `IPv4#to_string`:
138
+
139
+ ip.to_string
140
+ #=> "172.16.10.l/24"
141
+
142
+ === Changing netmask
143
+
144
+ You can set a new prefix (netmask) after creating an IPv4
145
+ object. For example:
146
+
147
+ ip.prefix = 25
148
+
149
+ ip.to_string
150
+ #=> "172.16.10.l/25"
151
+
152
+ If you need to use a netmask in IPv4 format, you can achive so by
153
+ using the `IPv4#netmask=` method:
154
+
155
+ ip.netmask = "255.255.255.252"
156
+
157
+ ip.to_string
158
+ #=> "172.16.10.1/30"
159
+
160
+ === Working with networks, broadcasts and addresses
161
+
162
+ Some very important topics in dealing with IP addresses are the
163
+ concepts of +network+ and +broadcast+, as well as the addresses
164
+ included in a range.
165
+
166
+ When you specify an IPv4 address such as `172.16.10.1/24`, you are
167
+ actually handling two different information:
168
+
169
+ * The IP address itself, "172.16.10.1"
170
+ * The subnet mask which indicates the network
171
+
172
+ The network number is the IP which has all zeroes in the host
173
+ portion. In our example, because the prefix is 24, we identify our
174
+ network number to have the last 8 (32-24) bits all zeroes. Thus, IP
175
+ address `172.16.10.1/24` belongs to network `172.16.10.0/24`.
176
+
177
+ This is very important because, for instance, IP `172.16.10.1/16` is
178
+ very different to the previous one, belonging to the very different
179
+ network `172.16.0.0/16`.
180
+
181
+ ==== Networks
182
+
183
+ With IPAddress it's very easy to calculate the network for an IP
184
+ address:
185
+
186
+ ip = IPAddress "172.16.10.1/24"
187
+
188
+ net = ip.network
189
+ #=> #<IPAddress::IPv4:0xb7a5ab24 @octets=[172, 16, 10, 0],
190
+ @prefix=24,
191
+ @address="172.16.10.0">
192
+ net.to_string
193
+ #=> "172.16.10.0/24"
194
+
195
+ Method IPv4#network creates a new IPv4 object from the network
196
+ number, calculated after the original object. We want to outline here
197
+ that the network address is a perfect legitimate IPv4 address, which
198
+ just happen to have all zeroes in the host portion.
199
+
200
+ You can use method `IPv4#network?` to check whether an IP address is a
201
+ network or not:
202
+
203
+ ip1 = IPAddress "172.16.10.1/24"
204
+ ip2 = IPAddress "172.16.10.4/30"
205
+
206
+ ip1.network?
207
+ #=> false
208
+ ip2.network?
209
+ #=> true
210
+
211
+ ==== Broadcast
212
+
213
+ The broadcast address is the contrary than the network number: where
214
+ the network number has all zeroes in the host portion, the broadcast
215
+ address has all one's. For example, ip `172.16.10.1/24` has broadcast
216
+ `172.16.10.255/24`, where ip `172.16.10.1/16` has broadcast
217
+ `172.16.255.255/16`.
218
+
219
+ Method `IPv4#broadcast` has the same behavior as is `#network`
220
+ counterpart: it creates a new IPv4 object to handle the broadcast
221
+ address:
222
+
223
+ ip = IPAddress "172.16.10.1/24"
224
+
225
+ bcast = ip.broadcast
226
+ #=> #<IPAddress::IPv4:0xb7a406fc @octets=[172, 16, 10, 255],
227
+ @prefix=24,
228
+ @address="172.16.10.255">
229
+ bcast.to_string
230
+ #=> "172.16.10.255/24"
231
+
232
+ ==== Addresses, ranges and iterators
233
+
234
+ So we see that the netmask essentially specifies a range for IP
235
+ addresses that are included in a network: all the addresses between
236
+ the network number and the broadcast. IPAddress has many methods to
237
+ iterate between those addresses. Let's start with `IPv4#each`, which
238
+ iterates over all addresses in a range
239
+
240
+ ip = IPAddress "172.16.10.1/24"
241
+
242
+ ip.each do |addr|
243
+ puts addr
244
+ end
245
+
246
+ It is important to note that it doesn't matter if the original IP is a
247
+ host IP or a network number (or a broadcast address): the #each method
248
+ only considers the range that the original IP specifies.
249
+
250
+ If you only want to iterate over hosts IP, use the `IPv4#each_host`
251
+ method:
252
+
253
+ ip = IPAddress "172.16.10.1/24"
254
+
255
+ ip.each_host do |host|
256
+ puts host
257
+ end
258
+
259
+ Methods `IPv4#first` and `IPv4#last` return a new object containing
260
+ respectively the first and the last host address in the range
261
+
262
+ ip = IPAddress "172.16.10.100/24"
263
+
264
+ ip.first.to_string
265
+ #=> "172.16.10.1/24"
266
+
267
+ ip.last.to_string
268
+ #=> "172.16.10.254/24"
269
+
270
+ Checking if an address is loopback is easy with the `IPv4#loopback?`
271
+ method:
272
+
273
+ ip = IPAddress "127.0.0.1"
274
+
275
+ ip.loopback?
276
+ #=> true
277
+
278
+ Checking if an address is in the multicast range can be done using the `IPv4#multicast?`
279
+ method:
280
+
281
+ ip = IPAddress "224.0.0.1/32"
282
+
283
+ ip.multicast?
284
+ #=> true
285
+
286
+ The ability to generate a range also exists by using the `IPv4#to()` method. This allows you to create a subnet agnostic range based off a fixed amount.
287
+
288
+ ip = IPAddress "172.16.10.100/24"
289
+ ip.to('172.16.10.110')
290
+ #=> ["172.16.10.100", ..., "172.16.10.110"]
291
+
292
+ === IP special formats
293
+
294
+ The IPAddress library provides a complete set of methods to access an
295
+ IPv4 address in special formats, such as binary, 32 bits unsigned int,
296
+ data and hexadecimal.
297
+
298
+ Let's take the following IPv4 as an example:
299
+
300
+ ip = IPAddress "172.16.10.1/24"
301
+
302
+ ip.address
303
+ #=> "172.16.10.1"
304
+
305
+ The first thing to highlight here is that all these conversion methods
306
+ only take into consideration the address portion of an IPv4 object and
307
+ not the prefix (netmask).
308
+
309
+ So, to express the address in binary format, use the `IPv4#bits` method:
310
+
311
+ ip.bits
312
+ #=> "10101100000100000000101000000001"
313
+
314
+ To calculate the 32 bits unsigned int format of the ip address, use
315
+ the `IPv4#to_u32` method
316
+
317
+ ip.to_u32
318
+ #=> 2886732289
319
+
320
+ This method is the equivalent of the Unix call `pton()`, expressing an
321
+ IP address in the so called +network byte order+ notation. However, if
322
+ you want to transmit your IP over a network socket, you might need to
323
+ transform it in data format using the `IPv4#data` method:
324
+
325
+ ip.data
326
+ #=> "\254\020\n\001"
327
+
328
+ Also, you can transform an IPv4 address into a format which is
329
+ suitable to use in IPv4-IPv6 mapped addresses:
330
+
331
+ ip.to_ipv6
332
+ #=> "ac10:0a01"
333
+
334
+ Finally, much like `IPv4#to_ipv6` you can use to `IPv4#to_h` method to return a non-semicolon delineated string (useful with pcap/byte level usage):
335
+
336
+ ip.to_h
337
+ #=> "ac100a01"
338
+
339
+ === Classful networks
340
+
341
+ IPAddress allows you to create and manipulate objects using the old
342
+ and deprecated (but apparently still popular) classful networks concept.
343
+
344
+ Classful networks and addresses don't have a prefix: their subnet mask
345
+ is univocally identified by their address, and therefore divided in classes.
346
+ As per RFC 791, these classes are:
347
+
348
+ * Class A, from 0.0.0.0 to 127.255.255.255
349
+ * Class B, from 128.0.0.0 to 191.255.255.255
350
+ * Class C, from 192.0.0.0 to 255.255.255.255
351
+
352
+ Since classful networks here are only considered to calculate the default
353
+ prefix number, classes D and E are not considered.
354
+
355
+ To create a classful IP and prefix from an IP address, use the
356
+ IPv4::parse_classful method:
357
+
358
+ # classful ip
359
+ ip = IPAddress::IPv4::parse_classful "10.1.1.1"
360
+
361
+ ip.prefix
362
+ #=> 8
363
+
364
+ The method automatically created a new IPv4 object and assigned it
365
+ the correct prefix.
366
+
367
+ You can easily check which CLASSFUL network an IPv4 object belongs:
368
+
369
+ ip = IPAddress("10.0.0.1/24")
370
+ ip.a?
371
+ #=> true
372
+
373
+ ip = IPAddress("172.16.10.1/24")
374
+ ip.b?
375
+ #=> true
376
+
377
+ ip = IPAddress("192.168.1.1/30")
378
+ ip.c?
379
+ #=> true
380
+
381
+ Remember that these methods are only checking the address portion of an IP, and are
382
+ independent from its prefix, as classful networks have no concept of prefix.
383
+
384
+ For more information on CLASSFUL networks visit the
385
+ {Wikipedia page}[http://en.wikipedia.org/wiki/Classful_network]
386
+
387
+ === Network design with IPAddress
388
+
389
+ IPAddress includes a lot of useful methods to manipulate IPv4 and IPv6
390
+ networks and do some basic network design.
391
+
392
+ ==== Subnetting
393
+
394
+ The process of subnetting is the division of a network into smaller
395
+ (in terms of hosts capacity) networks, called subnets, so that they
396
+ all share a common root, which is the starting network.
397
+
398
+ For example, if you have network "172.16.10.0/24", we can subnet it
399
+ into 4 smaller subnets. The new prefix will be /26, because 4 is 2^2
400
+ and therefore we add 2 bits to the network prefix (24+2=26).
401
+
402
+ Subnetting is easy with IPAddress. You actually have two options:
403
+
404
+ * IPv4#subnet: specify a new prefix
405
+ * IPv4#split: tell IPAddress how many subnets you want to create.
406
+
407
+ Let's examine `IPv4#subnet` first. Say you have network "172.16.10.0/24"
408
+ and you want to subnet it into /26 networks. With IPAddress it's very
409
+ easy:
410
+
411
+ network = IPAddress "172.16.10.0/24"
412
+
413
+ subnets = network.subnet(26)
414
+
415
+ subnets.map{|i| i.to_string}
416
+ #=> ["172.16.10.0/26",
417
+ "172.16.10.64/26",
418
+ "172.16.10.128/26",
419
+ "172.16.10.192/26"]
420
+
421
+ As you can see, an Array has been created, containing 4 new IPv4 objects
422
+ representing the new subnets.
423
+
424
+ Another way to create subnets is to tell IPAddress how many subnets you'd
425
+ like to have, and letting the library calculate the new prefix for you.
426
+
427
+ Let's see how it works, using `IPv4#split` method. Say you want 4 new subnets:
428
+
429
+ network = IPAddress("172.16.10.0/24")
430
+
431
+ subnets = network.split(4)
432
+
433
+ subnets.map{|i| i.to_string}
434
+ #=> ["172.16.10.0/26",
435
+ "172.16.10.64/26",
436
+ "172.16.10.128/26",
437
+ "172.16.10.192/26"]
438
+
439
+ Hey, that's the same result as before! This actually makes sense, as the
440
+ two operations are complementary. When you use `IPv4#subnet` with the new
441
+ prefix, IPAddress will always create a number of subnets that is a power
442
+ of two. This is equivalent to use IPv4#split with a power of 2.
443
+
444
+ Where `IPv4#split` really shines is with the so called "uneven subnetting".
445
+ You are not limited to split a network into a power-of-two numbers of
446
+ subnets: IPAddress lets you create any number of subnets, and it will
447
+ try to organize the new created network in the best possible way, making
448
+ an efficient allocation of the space.
449
+
450
+ An example here is worth a thousand words. Let's use the same network
451
+ as the previous examples:
452
+
453
+ network = IPAddress("172.16.10.0/24")
454
+
455
+ How do we split this network into 3 subnets? Very easy:
456
+
457
+ subnets = network.split(3)
458
+
459
+ subnets.map{|i| i.to_string}
460
+ #=> ["172.16.10.0/26",
461
+ "172.16.10.64/26",
462
+ "172.16.10.128/25"]
463
+
464
+ As you can see, IPAddress tried to perform a good allocation by filling up
465
+ all the address space from the original network. There is no point in splitting
466
+ a network into 3 subnets like `172.16.10.0/26`, `172.16.10.64/26` and
467
+ `172.16.10.128/26`, as you would end up having `172.16.10.192/26` wasted (plus,
468
+ I suppose I wouldn't need a Ruby library to perform un-efficient IP
469
+ allocation, as I do that myself very well ;) ).
470
+
471
+ We can go even further and split into 11 subnets:
472
+
473
+ network.split(11)
474
+ #=> ["172.16.10.0/28", "172.16.10.16/28", "172.16.10.32/28",
475
+ "172.16.10.48/28", "172.16.10.64/28", "172.16.10.80/28",
476
+ "172.16.10.96/28", "172.16.10.112/28", "172.16.10.128/27",
477
+ "172.16.10.160/27", "172.16.10.192/26"]
478
+
479
+ As you can see, most of the networks are `/28`, with a few `/27` and one
480
+ `/26` to fill up the remaining space.
481
+
482
+ ==== Summarization
483
+
484
+ Summarization (or aggregation) is the process when two or more
485
+ networks are taken together to check if a supernet, including
486
+ all and only these networks, exists. If it exists then this supernet
487
+ is called the summarized (or aggregated) network.
488
+ It is very important to understand that summarization can only
489
+ occur if there are no holes in the aggregated network, or, in
490
+ other words, if the given networks fill completely the address space
491
+ of the supernet. So the two rules are:
492
+
493
+ 1) The aggregate network must contain +all+ the IP addresses of the
494
+ original networks;
495
+
496
+ 2) The aggregate network must contain +only+ the IP addresses of the
497
+ original networks;
498
+
499
+ A few examples will help clarify the above. Let's consider for
500
+ instance the following two networks:
501
+
502
+ ip1 = IPAddress("172.16.10.0/24")
503
+ ip2 = IPAddress("172.16.11.0/24")
504
+
505
+ These two networks can be expressed using only one IP address
506
+ network if we change the prefix. Let Ruby do the work:
507
+
508
+ IPAddress::IPv4::summarize(ip1,ip2).map(&:to_string)
509
+ #=> "172.16.10.0/23"
510
+
511
+ We note how the network `172.16.10.0/23` includes all the
512
+ addresses specified in the above networks, and (more important) includes
513
+ ONLY those addresses.
514
+
515
+ If we summarized +ip1+ and +ip2+ with the following network:
516
+
517
+ "172.16.0.0/16"
518
+
519
+ we would have satisfied rule #1 above, but not rule #2. So
520
+
521
+ "172.16.0.0/16"
522
+
523
+ is not an aggregate network for +ip1+ and +ip2+.
524
+
525
+ If it's not possible to compute a single aggregated network for
526
+ all the original networks, the method returns an array with all the
527
+ aggregate networks found. For example, the following four networks can be
528
+ aggregated in a single `/22`:
529
+
530
+ ip1 = IPAddress("10.0.0.1/24")
531
+ ip2 = IPAddress("10.0.1.1/24")
532
+ ip3 = IPAddress("10.0.2.1/24")
533
+ ip4 = IPAddress("10.0.3.1/24")
534
+
535
+ IPAddress::IPv4::summarize(ip1,ip2,ip3,ip4).map{|i| i.to_string}
536
+ #=> ["10.0.0.0/22"]
537
+
538
+ But the following networks can't be summarized in a single
539
+ network:
540
+
541
+ ip1 = IPAddress("10.0.1.1/24")
542
+ ip2 = IPAddress("10.0.2.1/24")
543
+ ip3 = IPAddress("10.0.3.1/24")
544
+ ip4 = IPAddress("10.0.4.1/24")
545
+
546
+ IPAddress::IPv4::summarize(ip1,ip2,ip3,ip4).map{|i| i.to_string}
547
+ #=> ["10.0.1.0/24","10.0.2.0/23","10.0.4.0/24"]
548
+
549
+ In this case, the two summarizables networks have been aggregated into
550
+ a single `/23`, while the other two networks have been left untouched.
551
+
552
+ ==== Supernetting
553
+
554
+ Supernetting is a different operation than aggregation, as it only
555
+ works on a single network and returns a new single IPv4 object,
556
+ representing the supernet.
557
+
558
+ Supernetting is similar to subnetting, except that you getting as a
559
+ result a network with a smaller prefix (bigger host space). For
560
+ example, given the network
561
+
562
+ ip = IPAddress("172.16.10.0/24")
563
+
564
+ you can supernet it with a new /23 prefix
565
+
566
+ ip.supernet(23).to_string
567
+ #=> "172.16.10.0/23"
568
+
569
+ However if you supernet it with a `/22` prefix, the network address will
570
+ change:
571
+
572
+ ip.supernet(22).to_string
573
+ #=> "172.16.8.0/22"
574
+
575
+ This is because `172.16.10.0/22` is not a network anymore, but an host
576
+ address.
577
+
578
+ == IPv6
579
+
580
+ IPAddress is not only fantastic for IPv4 addresses, it's also great to
581
+ handle IPv6 addresses family! Let's discover together how to use it in
582
+ our projects.
583
+
584
+ === IPv6 addresses
585
+
586
+ IPv6 addresses are 128 bits long, in contrast with IPv4 addresses
587
+ which are only 32 bits long. An IPv6 address is generally written as
588
+ eight groups of four hexadecimal digits, each group representing 16
589
+ bits or two octet. For example, the following is a valid IPv6
590
+ address:
591
+
592
+ 2001:0db8:0000:0000:0008:0800:200c:417a
593
+
594
+ Letters in an IPv6 address are usually written downcase, as per
595
+ RFC. You can create a new IPv6 object using uppercase letters, but
596
+ they will be converted.
597
+
598
+ ==== Compression
599
+
600
+ Since IPv6 addresses are very long to write, there are some
601
+ simplifications and compressions that you can use to shorten them.
602
+
603
+ * Leading zeroes: all the leading zeroes within a group can be
604
+ omitted: "0008" would become "8"
605
+
606
+ * A string of consecutive zeroes can be replaced by the string
607
+ "::". This can be only applied once.
608
+
609
+ Using compression, the IPv6 address written above can be shorten into
610
+ the following, equivalent, address
611
+
612
+ 2001:db8::8:800:200c:417a
613
+
614
+ This short version is often used in human representation.
615
+
616
+ ==== Network Mask
617
+
618
+ As we used to do with IPv4 addresses, an IPv6 address can be written
619
+ using the prefix notation to specify the subnet mask:
620
+
621
+ 2001:db8::8:800:200c:417a/64
622
+
623
+ The /64 part means that the first 64 bits of the address are
624
+ representing the network portion, and the last 64 bits are the host
625
+ portion.
626
+
627
+ === Using IPAddress with IPv6 addresses
628
+
629
+ All the IPv6 representations we've just seen are perfectly fine when
630
+ you want to create a new IPv6 address:
631
+
632
+ ip6 = IPAddress "2001:0db8:0000:0000:0008:0800:200C:417A"
633
+
634
+ ip6 = IPAddress "2001:db8:0:0:8:800:200C:417A"
635
+
636
+ ip6 = IPAddress "2001:db8:8:800:200C:417A"
637
+
638
+ All three are giving out the same IPv6 object. The default subnet mask
639
+ for an IPv6 is 128, as IPv6 addresses don't have classes like IPv4
640
+ addresses. If you want a different mask, you can go ahead and explicit
641
+ it:
642
+
643
+ ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
644
+
645
+ Access the address portion and the prefix by using the respective
646
+ methods:
647
+
648
+ ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
649
+
650
+ ip6.address
651
+ #=> "2001:0db8:0000:0000:0008:0800:200c:417a"
652
+
653
+ ip6.prefix
654
+ #=> 64
655
+
656
+ A compressed version of the IPv6 address can be obtained with the
657
+ `IPv6#compressed` method:
658
+
659
+ ip6 = IPAddress "2001:0db8:0000:0000:0008:200c:417a:00ab/64"
660
+
661
+ ip6.compressed
662
+ #=> "2001:db8::8:800:200c:417a"
663
+
664
+ === Handling the IPv6 address
665
+
666
+ Accessing the groups that form an IPv6 address is very easy with the
667
+ `IPv6#groups` method:
668
+
669
+ ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
670
+
671
+ ip6.groups
672
+ #=> [8193, 3512, 0, 0, 8, 2048, 8204, 16762]
673
+
674
+ As with IPv4 addresses, each individual group can be accessed using
675
+ the `IPv6#[]` shortcut method:
676
+
677
+ ip6[0]
678
+ #=> 8193
679
+ ip6[1]
680
+ #=> 3512
681
+ ip6[2]
682
+ #=> 0
683
+ ip6[3]
684
+ #=> 0
685
+
686
+ Note that each 16 bits group is expressed in its decimal form. You can
687
+ also obtain the groups into hexadecimal format using the `IPv6#hexs`
688
+ method:
689
+
690
+ ip6.hexs
691
+ #=> => ["2001", "0db8", "0000", "0000", "0008", "0800", "200c", "417a"]
692
+
693
+ A few other methods are available to transform an IPv6 address into
694
+ decimal representation, with `IPv6.to_i`
695
+
696
+ ip6.to_i
697
+ #=> 42540766411282592856906245548098208122
698
+
699
+ or to hexadecimal representation
700
+
701
+ ip6.to_hex
702
+ #=> "20010db80000000000080800200c417a"
703
+
704
+ To print out an IPv6 address in human readable form, use the `IPv6#to_s`, `IPv6#to_string`
705
+ and `IPv6#to_string_uncompressed` methods
706
+
707
+ ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
708
+
709
+ ip6.to_string
710
+ #=> "2001:db8::8:800:200c:417a/96"
711
+
712
+ ip6.to_string_uncompressed
713
+ #=> "2001:0db8:0000:0000:0008:0800:200c:417a/96"
714
+
715
+ As you can see, `IPv6.to_string` prints out the compressed form, while
716
+ `IPv6.to_string_uncompressed` uses the expanded version.
717
+
718
+ ==== Compressing and uncompressing
719
+
720
+ If you have a string representing an IPv6 address, you can easily
721
+ compress it and uncompress it using the two class methods IPv6::expand
722
+ and IPv6::compress.
723
+
724
+ For example, let's say you have the following uncompressed IPv6
725
+ address:
726
+
727
+ ip6str = "2001:0DB8:0000:CD30:0000:0000:0000:0000"
728
+
729
+ Here is the compressed version:
730
+
731
+ IPAddress::IPv6.compress ip6str
732
+ #=> "2001:db8:0:cd30::"
733
+
734
+ The other way works as well:
735
+
736
+ ip6str = "2001:db8:0:cd30::"
737
+
738
+ IPAddress::IPv6.expand ip6str
739
+ #=> "2001:0DB8:0000:CD30:0000:0000:0000:0000"
740
+
741
+ These methods can be used when you don't want to create a new object
742
+ just for expanding or compressing an address (although a new object is
743
+ actually created internally).
744
+
745
+ === New IPv6 address from other formats
746
+
747
+ You can create a new IPv6 address from different formats than just a
748
+ string representing the colon-hex groups.
749
+
750
+ For instance, if you have a data stream, you can use `IPv6::parse_data`,
751
+ like in the following example:
752
+
753
+ data = " \001\r\270\000\000\000\000\000\b\b\000 \fAz"
754
+
755
+ ip6 = IPAddress::IPv6::parse_data data
756
+ ip6.prefix = 64
757
+
758
+ ip6.to_string
759
+ #=> "2001:db8::8:800:200c:417a/64"
760
+
761
+ A new IPv6 address can also be created from an unsigned 128 bits
762
+ integer:
763
+
764
+ u128 = 42540766411282592856906245548098208122
765
+
766
+ ip6 = IPAddress::IPv6::parse_u128 u128
767
+ ip6.prefix = 64
768
+
769
+ ip6.to_string
770
+ #=>"2001:db8::8:800:200c:417a/64"
771
+
772
+ Finally, a new IPv6 address can be created from an hex string:
773
+
774
+ hex = "20010db80000000000080800200c417a"
775
+
776
+ ip6 = IPAddress::IPv6::parse_hex hex
777
+ ip6.prefix = 64
778
+
779
+ ip6.to_string
780
+ #=> "2001:db8::8:800:200c:417a/64"
781
+
782
+ === Special IPv6 addresses
783
+
784
+ Some IPv6 have a special meaning and are expressed in a special form,
785
+ quite different than an usual IPv6 address. IPAddress has built-in
786
+ support for unspecified, loopback and mapped IPv6 addresses.
787
+
788
+ ==== Unspecified address
789
+
790
+ The address with all zero bits is called the +unspecified+ address
791
+ (corresponding to `0.0.0.0` in IPv4). It should be something like this:
792
+
793
+ 0000:0000:0000:0000:0000:0000:0000:0000
794
+
795
+ but, with the use of compression, it is usually written as just two
796
+ colons:
797
+
798
+ ::
799
+
800
+ or, specifying the netmask:
801
+
802
+ ::/128
803
+
804
+ With IPAddress, create a new unspecified IPv6 address using its own
805
+ subclass:
806
+
807
+ ip = IPAddress::IPv6::Unspecified.new
808
+
809
+ ip.to_string
810
+ #=> "::/128"
811
+
812
+ You can easily check if an IPv6 object is an unspecified address by
813
+ using the IPv6#unspecified? method
814
+
815
+ ip.unspecified?
816
+ #=> true
817
+
818
+ An unspecified IPv6 address can also be created with the wrapper
819
+ method, like we've seen before
820
+
821
+ ip = IPAddress "::"
822
+
823
+ ip.unspecified?
824
+ #=> true
825
+
826
+ This address must never be assigned to an interface and is to be used
827
+ only in software before the application has learned its host's source
828
+ address appropriate for a pending connection. Routers must not forward
829
+ packets with the unspecified address.
830
+
831
+ ==== Loopback address
832
+
833
+ The loopback address is a unicast localhost address. If an
834
+ application in a host sends packets to this address, the IPv6 stack
835
+ will loop these packets back on the same virtual interface.
836
+
837
+ Loopback addresses are expressed in the following form:
838
+
839
+ ::1
840
+
841
+ or, with their appropriate prefix,
842
+
843
+ ::1/128
844
+
845
+ As for the unspecified addresses, IPv6 loopbacks can be created with
846
+ IPAddress calling their own class:
847
+
848
+ ip = IPAddress::IPv6::Loopback.new
849
+
850
+ ip.to_string
851
+ #=> "::1/128"
852
+
853
+ or by using the wrapper:
854
+
855
+ ip = IPAddress "::1"
856
+
857
+ ip.to_string
858
+ #=> "::1/128"
859
+
860
+ Checking if an address is loopback is easy with the `IPv6#loopback?`
861
+ method:
862
+
863
+ ip.loopback?
864
+ #=> true
865
+
866
+ The IPv6 loopback address corresponds to `127.0.0.1` in IPv4.
867
+
868
+ ==== Mapped address
869
+
870
+ It is usually identified as a IPv4 mapped IPv6 address, a particular
871
+ IPv6 address which aids the transition from IPv4 to IPv6. The
872
+ structure of the address is
873
+
874
+ ::ffff:w.y.x.z
875
+
876
+ where `w.x.y.z` is a normal IPv4 address. For example, the following is
877
+ a mapped IPv6 address:
878
+
879
+ ::ffff:192.168.100.1
880
+
881
+ IPAddress is very powerful in handling mapped IPv6 addresses, as the
882
+ IPv4 portion is stored internally as a normal IPv4 object. Let's have
883
+ a look at some examples. To create a new mapped address, just use the
884
+ class builder itself
885
+
886
+ ip6 = IPAddress::IPv6::Mapped.new "::ffff:172.16.10.1/128"
887
+
888
+ or just use the wrapper method
889
+
890
+ ip6 = IPAddress "::ffff:172.16.10.1/128"
891
+
892
+ Let's check it's really a mapped address:
893
+
894
+ ip6.mapped?
895
+ #=> true
896
+
897
+ ip6.to_string
898
+ #=> "::ffff:172.16.10.1/128"
899
+
900
+ Now with the `#ipv4` attribute, we can easily access the IPv4 portion
901
+ of the mapped IPv6 address:
902
+
903
+ ip6.ipv4.address
904
+ #=> "172.16.10.1"
905
+
906
+ Internally, the IPv4 address is stored as two 16 bits
907
+ groups. Therefore all the usual methods for an IPv6 address are
908
+ working perfectly fine:
909
+
910
+ ip6.to_hex
911
+ #=> "00000000000000000000ffffac100a01"
912
+
913
+ ip6.address
914
+ #=> "0000:0000:0000:0000:0000:ffff:ac10:0a01"
915
+
916
+ A mapped IPv6 can also be created just by specify the address in the
917
+ following format:
918
+
919
+ ip6 = IPAddress "::172.16.10.1"
920
+
921
+ That is, two colons and the IPv4 address. However, as by RFC, the `ffff`
922
+ group will be automatically added at the beginning
923
+
924
+ ip6.to_string
925
+ => "::ffff:172.16.10.1/128"
926
+
927
+ making it a mapped IPv6 compatible address.
928
+
929
+ == Why not using IPAddr?
930
+
931
+ IPAddr is the IP addresses library that comes with Ruby standard
932
+ lib. We found this library, although very well written, not very
933
+ suitable for all our needs, and not very flexible.
934
+
935
+ Some quick examples of things you can't do with IPAddr:
936
+
937
+ * store both the address and the prefix information
938
+ * quickly find the broadcast address of a network
939
+ * iterate over hosts
940
+ * perform subnetting or network aggregation
941
+
942
+ Many methods and procedures are so old that they have been
943
+ declared deprecated by the IETF, and some others have bugs in their
944
+ implementation.
945
+
946
+ Moreover, IPAddress is more robust and is already around 50% faster than IPAddr,
947
+ in addition to provide an organic API with logical separation and OO structure.
948
+
949
+ We hope that IPAddress will address all these issues and meet all your
950
+ needs in network programming.
951
+
952
+
953
+ == Thanks to
954
+
955
+ Thanks to Luca Russo (vargolo) and Simone Carletti
956
+ (weppos) for all the support and technical review. Thanks to Marco Beri,
957
+ Bryan T. Richardson, Nicolas Fevrier, jdpace, Daniele Alessandri, jrdioko,
958
+ Ghislain Charrier, Pawel Krzesniak, Mark Sullivan, Leif Gensert,
959
+ Erik Ahlström, Peter Vandenberk and Steve Rawlinson for their support,
960
+ feedback and bug reports.
961
+
962
+ == Copyright
963
+
964
+ Copyright (c) 2009-2015 Marco Ceresa and Mike Mackintosh. See LICENSE for details.