PageRenderTime 63ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/ipaddress.rb

https://gitlab.com/intruxxer/ipaddress
Ruby | 201 lines | 61 code | 15 blank | 125 comment | 5 complexity | 591d49c27ab82886cd69ebb30f94a31a MD5 | raw file
  1. #
  2. # = IPAddress
  3. #
  4. # A ruby library to manipulate IPv4 and IPv6 addresses
  5. #
  6. #
  7. # Package:: IPAddress
  8. # Author:: Marco Ceresa <ceresa@ieee.org>
  9. # License:: Ruby License
  10. #
  11. #--
  12. #
  13. #++
  14. require 'ipaddress/ipv4'
  15. require 'ipaddress/ipv6'
  16. module IPAddress
  17. NAME = "IPAddress"
  18. GEM = "ipaddress"
  19. AUTHORS = ["Marco Ceresa <ceresa@ieee.org>"]
  20. #
  21. # Parse the argument string to create a new
  22. # IPv4, IPv6 or Mapped IP object
  23. #
  24. # ip = IPAddress.parse "172.16.10.1/24"
  25. # ip6 = IPAddress.parse "2001:db8::8:800:200c:417a/64"
  26. # ip_mapped = IPAddress.parse "::ffff:172.16.10.1/128"
  27. #
  28. # All the object created will be instances of the
  29. # correct class:
  30. #
  31. # ip.class
  32. # #=> IPAddress::IPv4
  33. # ip6.class
  34. # #=> IPAddress::IPv6
  35. # ip_mapped.class
  36. # #=> IPAddress::IPv6::Mapped
  37. #
  38. def IPAddress::parse(str)
  39. case str
  40. when /:.+\./
  41. IPAddress::IPv6::Mapped.new(str)
  42. when /\./
  43. IPAddress::IPv4.new(str)
  44. when /:/
  45. IPAddress::IPv6.new(str)
  46. else
  47. raise ArgumentError, "Unknown IP Address #{str}"
  48. end
  49. end
  50. #
  51. # True if the object is an IPv4 address
  52. #
  53. # ip = IPAddress("192.168.10.100/24")
  54. #
  55. # ip.ipv4?
  56. # #-> true
  57. #
  58. def ipv4?
  59. self.kind_of? IPAddress::IPv4
  60. end
  61. #
  62. # True if the object is an IPv6 address
  63. #
  64. # ip = IPAddress("192.168.10.100/24")
  65. #
  66. # ip.ipv6?
  67. # #-> false
  68. #
  69. def ipv6?
  70. self.kind_of? IPAddress::IPv6
  71. end
  72. #
  73. # Checks if the given string is a valid IP address,
  74. # either IPv4 or IPv6
  75. #
  76. # Example:
  77. #
  78. # IPAddress::valid? "2002::1"
  79. # #=> true
  80. #
  81. # IPAddress::valid? "10.0.0.256"
  82. # #=> false
  83. #
  84. def self.valid?(addr)
  85. valid_ipv4?(addr) || valid_ipv6?(addr)
  86. end
  87. #
  88. # Checks if the given string is a valid IPv4 address
  89. #
  90. # Example:
  91. #
  92. # IPAddress::valid_ipv4? "2002::1"
  93. # #=> false
  94. #
  95. # IPAddress::valid_ipv4? "172.16.10.1"
  96. # #=> true
  97. #
  98. def self.valid_ipv4?(addr)
  99. if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr
  100. return $~.captures.all? {|i| i.to_i < 256}
  101. end
  102. false
  103. end
  104. #
  105. # Checks if the argument is a valid IPv4 netmask
  106. # expressed in dotted decimal format.
  107. #
  108. # IPAddress.valid_ipv4_netmask? "255.255.0.0"
  109. # #=> true
  110. #
  111. def self.valid_ipv4_netmask?(addr)
  112. arr = addr.split(".").map{|i| i.to_i}.pack("CCCC").unpack("B*").first.scan(/01/)
  113. arr.empty? && valid_ipv4?(addr)
  114. rescue
  115. return false
  116. end
  117. #
  118. # Checks if the given string is a valid IPv6 address
  119. #
  120. # Example:
  121. #
  122. # IPAddress::valid_ipv6? "2002::1"
  123. # #=> true
  124. #
  125. # IPAddress::valid_ipv6? "2002::DEAD::BEEF"
  126. # #=> false
  127. #
  128. def self.valid_ipv6?(addr)
  129. # https://gist.github.com/cpetschnig/294476
  130. # http://forums.intermapper.com/viewtopic.php?t=452
  131. return true if /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/ =~ addr
  132. false
  133. end
  134. #
  135. # Deprecate method
  136. #
  137. def self.deprecate(message = nil) # :nodoc:
  138. message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
  139. warn("DEPRECATION WARNING: #{message}")
  140. end
  141. end # module IPAddress
  142. #
  143. # IPAddress is a wrapper method built around
  144. # IPAddress's library classes. Its purpouse is to
  145. # make you indipendent from the type of IP address
  146. # you're going to use.
  147. #
  148. # For example, instead of creating the three types
  149. # of IP addresses using their own contructors
  150. #
  151. # ip = IPAddress::IPv4.new "172.16.10.1/24"
  152. # ip6 = IPAddress::IPv6.new "2001:db8::8:800:200c:417a/64"
  153. # ip_mapped = IPAddress::IPv6::Mapped "::ffff:172.16.10.1/128"
  154. #
  155. # you can just use the IPAddress wrapper:
  156. #
  157. # ip = IPAddress "172.16.10.1/24"
  158. # ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
  159. # ip_mapped = IPAddress "::ffff:172.16.10.1/128"
  160. #
  161. # All the object created will be instances of the
  162. # correct class:
  163. #
  164. # ip.class
  165. # #=> IPAddress::IPv4
  166. # ip6.class
  167. # #=> IPAddress::IPv6
  168. # ip_mapped.class
  169. # #=> IPAddress::IPv6::Mapped
  170. #
  171. def IPAddress(str)
  172. IPAddress::parse str
  173. end
  174. #
  175. # Compatibility with Ruby 1.8
  176. #
  177. if RUBY_VERSION =~ /1\.8/
  178. class Hash # :nodoc:
  179. alias :key :index
  180. end
  181. module Math # :nodoc:
  182. def Math.log2(n)
  183. log(n) / log(2)
  184. end
  185. end
  186. end