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

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

    #Turns this IPv6 address into a Dnsruby::Name
    #--    
    # ip6.arpa should be searched too. [RFC3152]
    def to_name
      return Name.create(
        #                           @address.unpack("H32")[0].split(//).reverse + ['ip6', 'arpa'])
        @address.unpack("H32")[0].split(//).reverse.join(".") + ".ip6.arpa")
    end
    
    def ==(other) #:nodoc:
      return @address == other.address
    end
    
    def eql?(other) #:nodoc:
      return self == other
    end
    
    def hash
      return @address.hash
    end
  end
end
Back to Top