PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Merlin/External.LCA_RESTRICTED/Languages/Ruby/ruby-1.8.6p368/lib/ruby/1.8/ipaddr.rb

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