source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/ipaddr.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 20.6 KB
Line 
1#
2# ipaddr.rb - A class to manipulate an IP address
3#
4# Copyright (c) 2002 Hajimu UMEMOTO <[email protected]>.
5# All rights reserved.
6#
7# You can redistribute and/or modify it under the same terms as Ruby.
8#
9# $Id: ipaddr.rb 11708 2007-02-12 23:01:19Z shyouhei $
10#
11# TODO:
12# - scope_id support
13require 'socket'
14
15unless Socket.const_defined? "AF_INET6"
16 class Socket
17 AF_INET6 = Object.new
18 end
19
20 class << IPSocket
21 def valid_v4?(addr)
22 if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr
23 return $~.captures.all? {|i| i.to_i < 256}
24 end
25 return false
26 end
27
28 def valid_v6?(addr)
29 # IPv6 (normal)
30 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*\Z/ =~ addr
31 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr
32 return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr
33 # IPv6 (IPv4 compat)
34 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:/ =~ addr && valid_v4?($')
35 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($')
36 return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($')
37
38 false
39 end
40
41 def valid?(addr)
42 valid_v4?(addr) || valid_v6?(addr)
43 end
44
45 alias getaddress_orig getaddress
46 def getaddress(s)
47 if valid?(s)
48 s
49 elsif /\A[-A-Za-z\d.]+\Z/ =~ s
50 getaddress_orig(s)
51 else
52 raise ArgumentError, "invalid address"
53 end
54 end
55 end
56end
57
58# IPAddr provides a set of methods to manipulate an IP address. Both IPv4 and
59# IPv6 are supported.
60#
61# == Example
62#
63# require 'ipaddr'
64#
65# ipaddr1 = IPAddr.new "3ffe:505:2::1"
66#
67# p ipaddr1 #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
68#
69# p ipaddr1.to_s #=> "3ffe:505:2::1"
70#
71# ipaddr2 = ipaddr1.mask(48) #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>
72#
73# p ipaddr2.to_s #=> "3ffe:505:2::"
74#
75# ipaddr3 = IPAddr.new "192.168.2.0/24"
76#
77# p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
78
79class IPAddr
80
81 IN4MASK = 0xffffffff
82 IN6MASK = 0xffffffffffffffffffffffffffffffff
83 IN6FORMAT = (["%.4x"] * 8).join(':')
84
85 # Returns the address family of this IP address.
86 attr :family
87
88 # Creates a new ipaddr containing the given network byte ordered
89 # string form of an IP address.
90 def IPAddr::new_ntoh(addr)
91 return IPAddr.new(IPAddr::ntop(addr))
92 end
93
94 # Convert a network byte ordered string form of an IP address into
95 # human readable form.
96 def IPAddr::ntop(addr)
97 case addr.size
98 when 4
99 s = addr.unpack('C4').join('.')
100 when 16
101 s = IN6FORMAT % addr.unpack('n8')
102 else
103 raise ArgumentError, "unsupported address family"
104 end
105 return s
106 end
107
108 # Returns a new ipaddr built by bitwise AND.
109 def &(other)
110 return self.clone.set(@addr & other.to_i)
111 end
112
113 # Returns a new ipaddr built by bitwise OR.
114 def |(other)
115 return self.clone.set(@addr | other.to_i)
116 end
117
118 # Returns a new ipaddr built by bitwise right-shift.
119 def >>(num)
120 return self.clone.set(@addr >> num)
121 end
122
123 # Returns a new ipaddr built by bitwise left shift.
124 def <<(num)
125 return self.clone.set(addr_mask(@addr << num))
126 end
127
128 # Returns a new ipaddr built by bitwise negation.
129 def ~
130 return self.clone.set(addr_mask(~@addr))
131 end
132
133 # Returns true if two ipaddr are equal.
134 def ==(other)
135 if other.kind_of?(IPAddr) && @family != other.family
136 return false
137 end
138 return (@addr == other.to_i)
139 end
140
141 # Returns a new ipaddr built by masking IP address with the given
142 # prefixlen/netmask. (e.g. 8, 64, "255.255.255.0", etc.)
143 def mask(prefixlen)
144 return self.clone.mask!(prefixlen)
145 end
146
147 # Returns true if the given ipaddr is in the range.
148 #
149 # e.g.:
150 # require 'ipaddr'
151 # net1 = IPAddr.new("192.168.2.0/24")
152 # p net1.include?(IPAddr.new("192.168.2.0")) #=> true
153 # p net1.include?(IPAddr.new("192.168.2.255")) #=> true
154 # p net1.include?(IPAddr.new("192.168.3.0")) #=> false
155 def include?(other)
156 if ipv4_mapped?
157 if (@mask_addr >> 32) != 0xffffffffffffffffffffffff
158 return false
159 end
160 mask_addr = (@mask_addr & IN4MASK)
161 addr = (@addr & IN4MASK)
162 family = Socket::AF_INET
163 else
164 mask_addr = @mask_addr
165 addr = @addr
166 family = @family
167 end
168 if other.kind_of?(IPAddr)
169 if other.ipv4_mapped?
170 other_addr = (other.to_i & IN4MASK)
171 other_family = Socket::AF_INET
172 else
173 other_addr = other.to_i
174 other_family = other.family
175 end
176 else # Not IPAddr - assume integer in same family as us
177 other_addr = other.to_i
178 other_family = family
179 end
180
181 if family != other_family
182 return false
183 end
184 return ((addr & mask_addr) == (other_addr & mask_addr))
185 end
186 alias === include?
187
188 # Returns the integer representation of the ipaddr.
189 def to_i
190 return @addr
191 end
192
193 # Returns a string containing the IP address representation.
194 def to_s
195 str = to_string
196 return str if ipv4?
197
198 str.gsub!(/\b0{1,3}([\da-f]+)\b/i, '\1')
199 loop do
200 break if str.sub!(/\A0:0:0:0:0:0:0:0\Z/, '::')
201 break if str.sub!(/\b0:0:0:0:0:0:0\b/, ':')
202 break if str.sub!(/\b0:0:0:0:0:0\b/, ':')
203 break if str.sub!(/\b0:0:0:0:0\b/, ':')
204 break if str.sub!(/\b0:0:0:0\b/, ':')
205 break if str.sub!(/\b0:0:0\b/, ':')
206 break if str.sub!(/\b0:0\b/, ':')
207 break
208 end
209 str.sub!(/:{3,}/, '::')
210
211 if /\A::(ffff:)?([\da-f]{1,4}):([\da-f]{1,4})\Z/i =~ str
212 str = sprintf('::%s%d.%d.%d.%d', $1, $2.hex / 256, $2.hex % 256, $3.hex / 256, $3.hex % 256)
213 end
214
215 str
216 end
217
218 # Returns a string containing the IP address representation in
219 # canonical form.
220 def to_string
221 return _to_string(@addr)
222 end
223
224 # Returns a network byte ordered string form of the IP address.
225 def hton
226 case @family
227 when Socket::AF_INET
228 return [@addr].pack('N')
229 when Socket::AF_INET6
230 return (0..7).map { |i|
231 (@addr >> (112 - 16 * i)) & 0xffff
232 }.pack('n8')
233 else
234 raise "unsupported address family"
235 end
236 end
237
238 # Returns true if the ipaddr is an IPv4 address.
239 def ipv4?
240 return @family == Socket::AF_INET
241 end
242
243 # Returns true if the ipaddr is an IPv6 address.
244 def ipv6?
245 return @family == Socket::AF_INET6
246 end
247
248 # Returns true if the ipaddr is an IPv4-mapped IPv6 address.
249 def ipv4_mapped?
250 return ipv6? && (@addr >> 32) == 0xffff
251 end
252
253 # Returns true if the ipaddr is an IPv4-compatible IPv6 address.
254 def ipv4_compat?
255 if !ipv6? || (@addr >> 32) != 0
256 return false
257 end
258 a = (@addr & IN4MASK)
259 return a != 0 && a != 1
260 end
261
262 # Returns a new ipaddr built by converting the native IPv4 address
263 # into an IPv4-mapped IPv6 address.
264 def ipv4_mapped
265 if !ipv4?
266 raise ArgumentError, "not an IPv4 address"
267 end
268 return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
269 end
270
271 # Returns a new ipaddr built by converting the native IPv4 address
272 # into an IPv4-compatible IPv6 address.
273 def ipv4_compat
274 if !ipv4?
275 raise ArgumentError, "not an IPv4 address"
276 end
277 return self.clone.set(@addr, Socket::AF_INET6)
278 end
279
280 # Returns a new ipaddr built by converting the IPv6 address into a
281 # native IPv4 address. If the IP address is not an IPv4-mapped or
282 # IPv4-compatible IPv6 address, returns self.
283 def native
284 if !ipv4_mapped? && !ipv4_compat?
285 return self
286 end
287 return self.clone.set(@addr & IN4MASK, Socket::AF_INET)
288 end
289
290 # Returns a string for DNS reverse lookup. It returns a string in
291 # RFC3172 form for an IPv6 address.
292 def reverse
293 case @family
294 when Socket::AF_INET
295 return _reverse + ".in-addr.arpa"
296 when Socket::AF_INET6
297 return ip6_arpa
298 else
299 raise "unsupported address family"
300 end
301 end
302
303 # Returns a string for DNS reverse lookup compatible with RFC3172.
304 def ip6_arpa
305 if !ipv6?
306 raise ArgumentError, "not an IPv6 address"
307 end
308 return _reverse + ".ip6.arpa"
309 end
310
311 # Returns a string for DNS reverse lookup compatible with RFC1886.
312 def ip6_int
313 if !ipv6?
314 raise ArgumentError, "not an IPv6 address"
315 end
316 return _reverse + ".ip6.int"
317 end
318
319 # Returns a string containing a human-readable representation of the
320 # ipaddr. ("#<IPAddr: family:address/mask>")
321 def inspect
322 case @family
323 when Socket::AF_INET
324 af = "IPv4"
325 when Socket::AF_INET6
326 af = "IPv6"
327 else
328 raise "unsupported address family"
329 end
330 return sprintf("#<%s: %s:%s/%s>", self.class.name,
331 af, _to_string(@addr), _to_string(@mask_addr))
332 end
333
334 protected
335
336 def set(addr, *family)
337 case family[0] ? family[0] : @family
338 when Socket::AF_INET
339 if addr < 0 || addr > IN4MASK
340 raise ArgumentError, "invalid address"
341 end
342 when Socket::AF_INET6
343 if addr < 0 || addr > IN6MASK
344 raise ArgumentError, "invalid address"
345 end
346 else
347 raise ArgumentError, "unsupported address family"
348 end
349 @addr = addr
350 if family[0]
351 @family = family[0]
352 end
353 return self
354 end
355
356 def mask!(mask)
357 if mask.kind_of?(String)
358 if mask =~ /^\d+$/
359 prefixlen = mask.to_i
360 else
361 m = IPAddr.new(mask)
362 if m.family != @family
363 raise ArgumentError, "address family is not same"
364 end
365 @mask_addr = m.to_i
366 @addr &= @mask_addr
367 return self
368 end
369 else
370 prefixlen = mask
371 end
372 case @family
373 when Socket::AF_INET
374 if prefixlen < 0 || prefixlen > 32
375 raise ArgumentError, "invalid length"
376 end
377 masklen = 32 - prefixlen
378 @mask_addr = ((IN4MASK >> masklen) << masklen)
379 when Socket::AF_INET6
380 if prefixlen < 0 || prefixlen > 128
381 raise ArgumentError, "invalid length"
382 end
383 masklen = 128 - prefixlen
384 @mask_addr = ((IN6MASK >> masklen) << masklen)
385 else
386 raise "unsupported address family"
387 end
388 @addr = ((@addr >> masklen) << masklen)
389 return self
390 end
391
392 private
393
394 # Creates a new ipaddr containing the given human readable form of
395 # an IP address. It also accepts `address/prefixlen' and
396 # `address/mask'. When prefixlen or mask is specified, it returns a
397 # masked ipaddr. IPv6 address may beenclosed with `[' and `]'.
398 #
399 # Although an address family is determined automatically from a
400 # specified address, you can specify an address family explicitly by
401 # the optional second argument.
402 def initialize(addr = '::', family = Socket::AF_UNSPEC)
403 if !addr.kind_of?(String)
404 if family != Socket::AF_INET6 && family != Socket::AF_INET
405 raise ArgumentError, "unsupported address family"
406 end
407 set(addr, family)
408 @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
409 return
410 end
411 prefix, prefixlen = addr.split('/')
412 if prefix =~ /^\[(.*)\]$/i
413 prefix = $1
414 family = Socket::AF_INET6
415 end
416 # It seems AI_NUMERICHOST doesn't do the job.
417 #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
418 # Socket::AI_NUMERICHOST)
419 begin
420 IPSocket.getaddress(prefix) # test if address is vaild
421 rescue
422 raise ArgumentError, "invalid address"
423 end
424 @addr = @family = nil
425 if family == Socket::AF_UNSPEC || family == Socket::AF_INET
426 @addr = in_addr(prefix)
427 if @addr
428 @family = Socket::AF_INET
429 end
430 end
431 if !@addr && (family == Socket::AF_UNSPEC || family == Socket::AF_INET6)
432 @addr = in6_addr(prefix)
433 @family = Socket::AF_INET6
434 end
435 if family != Socket::AF_UNSPEC && @family != family
436 raise ArgumentError, "address family unmatch"
437 end
438 if prefixlen
439 mask!(prefixlen)
440 else
441 @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
442 end
443 end
444
445 def in_addr(addr)
446 if addr =~ /^\d+\.\d+\.\d+\.\d+$/
447 n = 0
448 addr.split('.').each { |i|
449 n <<= 8
450 n += i.to_i
451 }
452 return n
453 end
454 return nil
455 end
456
457 def in6_addr(left)
458 case left
459 when /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i
460 return in_addr($1) + 0xffff00000000
461 when /^::(\d+\.\d+\.\d+\.\d+)$/i
462 return in_addr($1)
463 when /[^0-9a-f:]/i
464 raise ArgumentError, "invalid address"
465 when /^(.*)::(.*)$/
466 left, right = $1, $2
467 else
468 right = ''
469 end
470 l = left.split(':')
471 r = right.split(':')
472 rest = 8 - l.size - r.size
473 if rest < 0
474 return nil
475 end
476 a = [l, Array.new(rest, '0'), r].flatten!
477 n = 0
478 a.each { |i|
479 n <<= 16
480 n += i.hex
481 }
482 return n
483 end
484
485 def addr_mask(addr)
486 case @family
487 when Socket::AF_INET
488 addr &= IN4MASK
489 when Socket::AF_INET6
490 addr &= IN6MASK
491 else
492 raise "unsupported address family"
493 end
494 return addr
495 end
496
497 def _reverse
498 case @family
499 when Socket::AF_INET
500 return (0..3).map { |i|
501 (@addr >> (8 * i)) & 0xff
502 }.join('.')
503 when Socket::AF_INET6
504 return ("%.32x" % @addr).reverse!.gsub!(/.(?!$)/, '\&.')
505 else
506 raise "unsupported address family"
507 end
508 end
509
510 def _to_string(addr)
511 case @family
512 when Socket::AF_INET
513 return (0..3).map { |i|
514 (addr >> (24 - 8 * i)) & 0xff
515 }.join('.')
516 when Socket::AF_INET6
517 return (("%.32x" % addr).gsub!(/.{4}(?!$)/, '\&:'))
518 else
519 raise "unsupported address family"
520 end
521 end
522
523end
524
525if $0 == __FILE__
526 eval DATA.read, nil, $0, __LINE__+4
527end
528
529__END__
530
531require 'test/unit'
532require 'test/unit/ui/console/testrunner'
533
534class TC_IPAddr < Test::Unit::TestCase
535 def test_s_new
536 assert_nothing_raised {
537 IPAddr.new("3FFE:505:ffff::/48")
538 IPAddr.new("0:0:0:1::")
539 IPAddr.new("2001:200:300::/48")
540 }
541
542 a = IPAddr.new
543 assert_equal("::", a.to_s)
544 assert_equal("0000:0000:0000:0000:0000:0000:0000:0000", a.to_string)
545 assert_equal(Socket::AF_INET6, a.family)
546
547 a = IPAddr.new("0123:4567:89ab:cdef:0ABC:DEF0:1234:5678")
548 assert_equal("123:4567:89ab:cdef:abc:def0:1234:5678", a.to_s)
549 assert_equal("0123:4567:89ab:cdef:0abc:def0:1234:5678", a.to_string)
550 assert_equal(Socket::AF_INET6, a.family)
551
552 a = IPAddr.new("3ffe:505:2::/48")
553 assert_equal("3ffe:505:2::", a.to_s)
554 assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0000", a.to_string)
555 assert_equal(Socket::AF_INET6, a.family)
556 assert_equal(false, a.ipv4?)
557 assert_equal(true, a.ipv6?)
558 assert_equal("#<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>", a.inspect)
559
560 a = IPAddr.new("3ffe:505:2::/ffff:ffff:ffff::")
561 assert_equal("3ffe:505:2::", a.to_s)
562 assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0000", a.to_string)
563 assert_equal(Socket::AF_INET6, a.family)
564
565 a = IPAddr.new("0.0.0.0")
566 assert_equal("0.0.0.0", a.to_s)
567 assert_equal("0.0.0.0", a.to_string)
568 assert_equal(Socket::AF_INET, a.family)
569
570 a = IPAddr.new("192.168.1.2")
571 assert_equal("192.168.1.2", a.to_s)
572 assert_equal("192.168.1.2", a.to_string)
573 assert_equal(Socket::AF_INET, a.family)
574 assert_equal(true, a.ipv4?)
575 assert_equal(false, a.ipv6?)
576
577 a = IPAddr.new("192.168.1.2/24")
578 assert_equal("192.168.1.0", a.to_s)
579 assert_equal("192.168.1.0", a.to_string)
580 assert_equal(Socket::AF_INET, a.family)
581 assert_equal("#<IPAddr: IPv4:192.168.1.0/255.255.255.0>", a.inspect)
582
583 a = IPAddr.new("192.168.1.2/255.255.255.0")
584 assert_equal("192.168.1.0", a.to_s)
585 assert_equal("192.168.1.0", a.to_string)
586 assert_equal(Socket::AF_INET, a.family)
587
588 assert_equal("0:0:0:1::", IPAddr.new("0:0:0:1::").to_s)
589 assert_equal("2001:200:300::", IPAddr.new("2001:200:300::/48").to_s)
590
591 assert_equal("2001:200:300::", IPAddr.new("[2001:200:300::]/48").to_s)
592
593 [
594 ["fe80::1%fxp0"],
595 ["::1/255.255.255.0"],
596 ["::1:192.168.1.2/120"],
597 [IPAddr.new("::1").to_i],
598 ["::ffff:192.168.1.2/120", Socket::AF_INET],
599 ["[192.168.1.2]/120"],
600 ].each { |args|
601 assert_raises(ArgumentError) {
602 IPAddr.new(*args)
603 }
604 }
605 end
606
607 def test_s_new_ntoh
608 addr = ''
609 IPAddr.new("1234:5678:9abc:def0:1234:5678:9abc:def0").hton.each_byte { |c|
610 addr += sprintf("%02x", c)
611 }
612 assert_equal("123456789abcdef0123456789abcdef0", addr)
613 addr = ''
614 IPAddr.new("123.45.67.89").hton.each_byte { |c|
615 addr += sprintf("%02x", c)
616 }
617 assert_equal(sprintf("%02x%02x%02x%02x", 123, 45, 67, 89), addr)
618 a = IPAddr.new("3ffe:505:2::")
619 assert_equal("3ffe:505:2::", IPAddr.new_ntoh(a.hton).to_s)
620 a = IPAddr.new("192.168.2.1")
621 assert_equal("192.168.2.1", IPAddr.new_ntoh(a.hton).to_s)
622 end
623
624 def test_ipv4_compat
625 a = IPAddr.new("::192.168.1.2")
626 assert_equal("::192.168.1.2", a.to_s)
627 assert_equal("0000:0000:0000:0000:0000:0000:c0a8:0102", a.to_string)
628 assert_equal(Socket::AF_INET6, a.family)
629 assert_equal(true, a.ipv4_compat?)
630 b = a.native
631 assert_equal("192.168.1.2", b.to_s)
632 assert_equal(Socket::AF_INET, b.family)
633 assert_equal(false, b.ipv4_compat?)
634
635 a = IPAddr.new("192.168.1.2")
636 b = a.ipv4_compat
637 assert_equal("::192.168.1.2", b.to_s)
638 assert_equal(Socket::AF_INET6, b.family)
639 end
640
641 def test_ipv4_mapped
642 a = IPAddr.new("::ffff:192.168.1.2")
643 assert_equal("::ffff:192.168.1.2", a.to_s)
644 assert_equal("0000:0000:0000:0000:0000:ffff:c0a8:0102", a.to_string)
645 assert_equal(Socket::AF_INET6, a.family)
646 assert_equal(true, a.ipv4_mapped?)
647 b = a.native
648 assert_equal("192.168.1.2", b.to_s)
649 assert_equal(Socket::AF_INET, b.family)
650 assert_equal(false, b.ipv4_mapped?)
651
652 a = IPAddr.new("192.168.1.2")
653 b = a.ipv4_mapped
654 assert_equal("::ffff:192.168.1.2", b.to_s)
655 assert_equal(Socket::AF_INET6, b.family)
656 end
657
658 def test_reverse
659 assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa", IPAddr.new("3ffe:505:2::f").reverse)
660 assert_equal("1.2.168.192.in-addr.arpa", IPAddr.new("192.168.2.1").reverse)
661 end
662
663 def test_ip6_arpa
664 assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa", IPAddr.new("3ffe:505:2::f").ip6_arpa)
665 assert_raises(ArgumentError) {
666 IPAddr.new("192.168.2.1").ip6_arpa
667 }
668 end
669
670 def test_ip6_int
671 assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.int", IPAddr.new("3ffe:505:2::f").ip6_int)
672 assert_raises(ArgumentError) {
673 IPAddr.new("192.168.2.1").ip6_int
674 }
675 end
676
677 def test_to_s
678 assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0001", IPAddr.new("3ffe:505:2::1").to_string)
679 assert_equal("3ffe:505:2::1", IPAddr.new("3ffe:505:2::1").to_s)
680 end
681end
682
683class TC_Operator < Test::Unit::TestCase
684
685 IN6MASK32 = "ffff:ffff::"
686 IN6MASK128 = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
687
688 def setup
689 @in6_addr_any = IPAddr.new()
690 @a = IPAddr.new("3ffe:505:2::/48")
691 @b = IPAddr.new("0:0:0:1::")
692 @c = IPAddr.new(IN6MASK32)
693 end
694 alias set_up setup
695
696 def test_or
697 assert_equal("3ffe:505:2:1::", (@a | @b).to_s)
698 a = @a
699 a |= @b
700 assert_equal("3ffe:505:2:1::", a.to_s)
701 assert_equal("3ffe:505:2::", @a.to_s)
702 assert_equal("3ffe:505:2:1::",
703 (@a | 0x00000000000000010000000000000000).to_s)
704 end
705
706 def test_and
707 assert_equal("3ffe:505::", (@a & @c).to_s)
708 a = @a
709 a &= @c
710 assert_equal("3ffe:505::", a.to_s)
711 assert_equal("3ffe:505:2::", @a.to_s)
712 assert_equal("3ffe:505::", (@a & 0xffffffff000000000000000000000000).to_s)
713 end
714
715 def test_shift_right
716 assert_equal("0:3ffe:505:2::", (@a >> 16).to_s)
717 a = @a
718 a >>= 16
719 assert_equal("0:3ffe:505:2::", a.to_s)
720 assert_equal("3ffe:505:2::", @a.to_s)
721 end
722
723 def test_shift_left
724 assert_equal("505:2::", (@a << 16).to_s)
725 a = @a
726 a <<= 16
727 assert_equal("505:2::", a.to_s)
728 assert_equal("3ffe:505:2::", @a.to_s)
729 end
730
731 def test_carrot
732 a = ~@in6_addr_any
733 assert_equal(IN6MASK128, a.to_s)
734 assert_equal("::", @in6_addr_any.to_s)
735 end
736
737 def test_equal
738 assert_equal(true, @a == IPAddr.new("3ffe:505:2::"))
739 assert_equal(false, @a == IPAddr.new("3ffe:505:3::"))
740 assert_equal(true, @a != IPAddr.new("3ffe:505:3::"))
741 assert_equal(false, @a != IPAddr.new("3ffe:505:2::"))
742 end
743
744 def test_mask
745 a = @a.mask(32)
746 assert_equal("3ffe:505::", a.to_s)
747 assert_equal("3ffe:505:2::", @a.to_s)
748 end
749
750 def test_include?
751 assert_equal(true, @a.include?(IPAddr.new("3ffe:505:2::")))
752 assert_equal(true, @a.include?(IPAddr.new("3ffe:505:2::1")))
753 assert_equal(false, @a.include?(IPAddr.new("3ffe:505:3::")))
754 net1 = IPAddr.new("192.168.2.0/24")
755 assert_equal(true, net1.include?(IPAddr.new("192.168.2.0")))
756 assert_equal(true, net1.include?(IPAddr.new("192.168.2.255")))
757 assert_equal(false, net1.include?(IPAddr.new("192.168.3.0")))
758 # test with integer parameter
759 int = (192 << 24) + (168 << 16) + (2 << 8) + 13
760
761 assert_equal(true, net1.include?(int))
762 assert_equal(false, net1.include?(int+255))
763
764 end
765
766end
Note: See TracBrowser for help on using the repository browser.