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

/vendor/Dnsruby-1.0/Dnsruby/ipv6.rb

https://github.com/adamwiggins/whatswrong
Ruby | 144 lines | 101 code | 13 blank | 30 comment | 13 complexity | b8e49f13ccf4c196368fe81414017aa3 MD5 | raw file
  1. #--
  2. #Copyright 2007 Nominet UK
  3. #
  4. #Licensed under the Apache License, Version 2.0 (the "License");
  5. #you may not use this file except in compliance with the License.
  6. #You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. #Unless required by applicable law or agreed to in writing, software
  11. #distributed under the License is distributed on an "AS IS" BASIS,
  12. #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. #See the License for the specific language governing permissions and
  14. #limitations under the License.
  15. #++
  16. module Dnsruby
  17. #Dnsruby::IPv6 class
  18. class IPv6
  19. #IPv6 address format a:b:c:d:e:f:g:h
  20. Regex_8Hex = /\A
  21. (?:[0-9A-Fa-f]{1,4}:){7}
  22. [0-9A-Fa-f]{1,4}
  23. \z/x
  24. #Compresses IPv6 format a::b
  25. Regex_CompressedHex = /\A
  26. ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
  27. ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
  28. \z/x
  29. # IPv4 mapped IPv6 address format a:b:c:d:e:f:w.x.y.z
  30. Regex_6Hex4Dec = /\A
  31. ((?:[0-9A-Fa-f]{1,4}:){6,6})
  32. (\d+)\.(\d+)\.(\d+)\.(\d+)
  33. \z/x
  34. # Compressed IPv4 mapped IPv6 address format a::b:w.x.y.z
  35. Regex_CompressedHex4Dec = /\A
  36. ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
  37. ((?:[0-9A-Fa-f]{1,4}:)*)
  38. (\d+)\.(\d+)\.(\d+)\.(\d+)
  39. \z/x
  40. # A composite IPv6 address RegExp
  41. Regex = /
  42. (?:#{Regex_8Hex}) |
  43. (?:#{Regex_CompressedHex}) |
  44. (?:#{Regex_6Hex4Dec}) |
  45. (?:#{Regex_CompressedHex4Dec})/x
  46. # Created a new IPv6 address from +arg+ which may be:
  47. #
  48. #* IPv6:: returns +arg+
  49. #* String:: +arg+ must match one of the IPv6::Regex* constants
  50. def self.create(arg)
  51. case arg
  52. when IPv6
  53. return arg
  54. when String
  55. address = ''
  56. if Regex_8Hex =~ arg
  57. arg.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
  58. elsif Regex_CompressedHex =~ arg
  59. prefix = $1
  60. suffix = $2
  61. a1 = ''
  62. a2 = ''
  63. prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
  64. suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
  65. omitlen = 16 - a1.length - a2.length
  66. address << a1 << "\0" * omitlen << a2
  67. elsif Regex_6Hex4Dec =~ arg
  68. prefix, a, b, c, d = $1, $2.to_i, $3.to_i, $4.to_i, $5.to_i
  69. if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
  70. prefix.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}
  71. address << [a, b, c, d].pack('CCCC')
  72. else
  73. raise ArgumentError.new("not numeric IPv6 address: " + arg)
  74. end
  75. elsif Regex_CompressedHex4Dec =~ arg
  76. prefix, suffix, a, b, c, d = $1, $2, $3.to_i, $4.to_i, $5.to_i, $6.to_i
  77. if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d
  78. a1 = ''
  79. a2 = ''
  80. prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}
  81. suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}
  82. omitlen = 12 - a1.length - a2.length
  83. address << a1 << "\0" * omitlen << a2 << [a, b, c, d].pack('CCCC')
  84. else
  85. raise ArgumentError.new("not numeric IPv6 address: " + arg)
  86. end
  87. else
  88. raise ArgumentError.new("not numeric IPv6 address: " + arg)
  89. end
  90. return IPv6.new(address)
  91. else
  92. raise ArgumentError.new("cannot interpret as IPv6 address: #{arg.inspect}")
  93. end
  94. end
  95. def initialize(address) #:nodoc:
  96. unless address.kind_of?(String) && address.length == 16
  97. raise ArgumentError.new('IPv6 address must be 16 bytes')
  98. end
  99. @address = address
  100. end
  101. # The raw IPv6 address as a String
  102. attr_reader :address
  103. def to_s
  104. address = sprintf("%X:%X:%X:%X:%X:%X:%X:%X", *@address.unpack("nnnnnnnn"))
  105. unless address.sub!(/(^|:)0(:0)+(:|$)/, '::')
  106. address.sub!(/(^|:)0(:|$)/, '::')
  107. end
  108. return address
  109. end
  110. def inspect #:nodoc:
  111. return "#<#{self.class} #{self.to_s}>"
  112. end
  113. #Turns this IPv6 address into a Dnsruby::Name
  114. #--
  115. # ip6.arpa should be searched too. [RFC3152]
  116. def to_name
  117. return Name.create(
  118. # @address.unpack("H32")[0].split(//).reverse + ['ip6', 'arpa'])
  119. @address.unpack("H32")[0].split(//).reverse.join(".") + ".ip6.arpa")
  120. end
  121. def ==(other) #:nodoc:
  122. return @address == other.address
  123. end
  124. def eql?(other) #:nodoc:
  125. return self == other
  126. end
  127. def hash
  128. return @address.hash
  129. end
  130. end
  131. end