echonet_lite 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (346) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +43 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/echonet_lite.gemspec +37 -0
  13. data/lib/echonet_lite.rb +149 -0
  14. data/lib/echonet_lite/version.rb +3 -0
  15. data/vendor/bundle/bin/htmldiff +29 -0
  16. data/vendor/bundle/bin/htmldiff.bat +6 -0
  17. data/vendor/bundle/bin/ldiff +29 -0
  18. data/vendor/bundle/bin/ldiff.bat +6 -0
  19. data/vendor/bundle/bin/rspec +27 -0
  20. data/vendor/bundle/bin/rspec.bat +6 -0
  21. data/vendor/bundle/cache/diff-lcs-1.3.gem +0 -0
  22. data/vendor/bundle/cache/echonet_lite-0.1.0.gem +0 -0
  23. data/vendor/bundle/cache/ipaddr-1.0.0.gem +0 -0
  24. data/vendor/bundle/cache/ipaddress-0.8.3.gem +0 -0
  25. data/vendor/bundle/cache/rspec-3.6.0.gem +0 -0
  26. data/vendor/bundle/cache/rspec-core-3.6.0.gem +0 -0
  27. data/vendor/bundle/cache/rspec-expectations-3.6.0.gem +0 -0
  28. data/vendor/bundle/cache/rspec-mocks-3.6.0.gem +0 -0
  29. data/vendor/bundle/cache/rspec-support-3.6.0.gem +0 -0
  30. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/GSET-c.ri +0 -0
  31. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/Hexadecimal_str-c.ri +0 -0
  32. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/Receive-c.ri +0 -0
  33. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/ReceivePrint-c.ri +0 -0
  34. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/SETC-c.ri +0 -0
  35. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/SETI-c.ri +0 -0
  36. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/cdesc-EL.ri +0 -0
  37. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/pattern-c.ri +0 -0
  38. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/search-c.ri +0 -0
  39. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/sendOPC1-c.ri +0 -0
  40. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/sendString-c.ri +0 -0
  41. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EL/udp_send-c.ri +0 -0
  42. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/EchonetLite/cdesc-EchonetLite.ri +0 -0
  43. data/vendor/bundle/doc/echonet_lite-0.1.0/ri/cache.ri +0 -0
  44. data/vendor/bundle/gems/diff-lcs-1.3/.rspec +1 -0
  45. data/vendor/bundle/gems/diff-lcs-1.3/Code-of-Conduct.md +74 -0
  46. data/vendor/bundle/gems/diff-lcs-1.3/Contributing.md +83 -0
  47. data/vendor/bundle/gems/diff-lcs-1.3/History.md +220 -0
  48. data/vendor/bundle/gems/diff-lcs-1.3/License.md +39 -0
  49. data/vendor/bundle/gems/diff-lcs-1.3/Manifest.txt +37 -0
  50. data/vendor/bundle/gems/diff-lcs-1.3/README.rdoc +84 -0
  51. data/vendor/bundle/gems/diff-lcs-1.3/Rakefile +57 -0
  52. data/vendor/bundle/gems/diff-lcs-1.3/autotest/discover.rb +1 -0
  53. data/vendor/bundle/gems/diff-lcs-1.3/bin/htmldiff +32 -0
  54. data/vendor/bundle/gems/diff-lcs-1.3/bin/ldiff +6 -0
  55. data/vendor/bundle/gems/diff-lcs-1.3/docs/COPYING.txt +339 -0
  56. data/vendor/bundle/gems/diff-lcs-1.3/docs/artistic.txt +127 -0
  57. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff-lcs.rb +3 -0
  58. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff/lcs.rb +725 -0
  59. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff/lcs/array.rb +7 -0
  60. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff/lcs/block.rb +37 -0
  61. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff/lcs/callbacks.rb +322 -0
  62. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff/lcs/change.rb +181 -0
  63. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff/lcs/htmldiff.rb +149 -0
  64. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff/lcs/hunk.rb +276 -0
  65. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff/lcs/internals.rb +307 -0
  66. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff/lcs/ldiff.rb +167 -0
  67. data/vendor/bundle/gems/diff-lcs-1.3/lib/diff/lcs/string.rb +5 -0
  68. data/vendor/bundle/gems/diff-lcs-1.3/spec/change_spec.rb +65 -0
  69. data/vendor/bundle/gems/diff-lcs-1.3/spec/diff_spec.rb +47 -0
  70. data/vendor/bundle/gems/diff-lcs-1.3/spec/fixtures/ds1.csv +50 -0
  71. data/vendor/bundle/gems/diff-lcs-1.3/spec/fixtures/ds2.csv +51 -0
  72. data/vendor/bundle/gems/diff-lcs-1.3/spec/hunk_spec.rb +72 -0
  73. data/vendor/bundle/gems/diff-lcs-1.3/spec/issues_spec.rb +49 -0
  74. data/vendor/bundle/gems/diff-lcs-1.3/spec/lcs_spec.rb +56 -0
  75. data/vendor/bundle/gems/diff-lcs-1.3/spec/ldiff_spec.rb +47 -0
  76. data/vendor/bundle/gems/diff-lcs-1.3/spec/patch_spec.rb +422 -0
  77. data/vendor/bundle/gems/diff-lcs-1.3/spec/sdiff_spec.rb +214 -0
  78. data/vendor/bundle/gems/diff-lcs-1.3/spec/spec_helper.rb +321 -0
  79. data/vendor/bundle/gems/diff-lcs-1.3/spec/traverse_balanced_spec.rb +310 -0
  80. data/vendor/bundle/gems/diff-lcs-1.3/spec/traverse_sequences_spec.rb +139 -0
  81. data/vendor/bundle/gems/echonet_lite-0.1.0/.gitignore +12 -0
  82. data/vendor/bundle/gems/echonet_lite-0.1.0/.rspec +2 -0
  83. data/vendor/bundle/gems/echonet_lite-0.1.0/.travis.yml +5 -0
  84. data/vendor/bundle/gems/echonet_lite-0.1.0/CODE_OF_CONDUCT.md +74 -0
  85. data/vendor/bundle/gems/echonet_lite-0.1.0/Gemfile +6 -0
  86. data/vendor/bundle/gems/echonet_lite-0.1.0/LICENSE.txt +21 -0
  87. data/vendor/bundle/gems/echonet_lite-0.1.0/README.md +43 -0
  88. data/vendor/bundle/gems/echonet_lite-0.1.0/Rakefile +6 -0
  89. data/vendor/bundle/gems/echonet_lite-0.1.0/bin/console +14 -0
  90. data/vendor/bundle/gems/echonet_lite-0.1.0/bin/setup +8 -0
  91. data/vendor/bundle/gems/echonet_lite-0.1.0/echonet_lite.gemspec +37 -0
  92. data/vendor/bundle/gems/echonet_lite-0.1.0/lib/echonet_lite.rb +149 -0
  93. data/vendor/bundle/gems/echonet_lite-0.1.0/lib/echonet_lite/version.rb +3 -0
  94. data/vendor/bundle/gems/ipaddr-1.0.0/.gitignore +9 -0
  95. data/vendor/bundle/gems/ipaddr-1.0.0/.travis.yml +6 -0
  96. data/vendor/bundle/gems/ipaddr-1.0.0/Gemfile +4 -0
  97. data/vendor/bundle/gems/ipaddr-1.0.0/LICENSE.txt +23 -0
  98. data/vendor/bundle/gems/ipaddr-1.0.0/README.md +54 -0
  99. data/vendor/bundle/gems/ipaddr-1.0.0/Rakefile +10 -0
  100. data/vendor/bundle/gems/ipaddr-1.0.0/bin/console +14 -0
  101. data/vendor/bundle/gems/ipaddr-1.0.0/bin/setup +8 -0
  102. data/vendor/bundle/gems/ipaddr-1.0.0/ipaddr.gemspec +28 -0
  103. data/vendor/bundle/gems/ipaddr-1.0.0/lib/ipaddr.rb +662 -0
  104. data/vendor/bundle/gems/ipaddress-0.8.3/.document +5 -0
  105. data/vendor/bundle/gems/ipaddress-0.8.3/.gitignore +18 -0
  106. data/vendor/bundle/gems/ipaddress-0.8.3/.rock.yml +5 -0
  107. data/vendor/bundle/gems/ipaddress-0.8.3/CHANGELOG.rdoc +115 -0
  108. data/vendor/bundle/gems/ipaddress-0.8.3/Gemfile +3 -0
  109. data/vendor/bundle/gems/ipaddress-0.8.3/LICENSE.txt +20 -0
  110. data/vendor/bundle/gems/ipaddress-0.8.3/README.rdoc +998 -0
  111. data/vendor/bundle/gems/ipaddress-0.8.3/Rakefile +66 -0
  112. data/vendor/bundle/gems/ipaddress-0.8.3/ipaddress.gemspec +26 -0
  113. data/vendor/bundle/gems/ipaddress-0.8.3/lib/ipaddress.rb +227 -0
  114. data/vendor/bundle/gems/ipaddress-0.8.3/lib/ipaddress/ipv4.rb +1114 -0
  115. data/vendor/bundle/gems/ipaddress-0.8.3/lib/ipaddress/ipv6.rb +895 -0
  116. data/vendor/bundle/gems/ipaddress-0.8.3/lib/ipaddress/mongoid.rb +75 -0
  117. data/vendor/bundle/gems/ipaddress-0.8.3/lib/ipaddress/prefix.rb +265 -0
  118. data/vendor/bundle/gems/ipaddress-0.8.3/lib/ipaddress/version.rb +3 -0
  119. data/vendor/bundle/gems/ipaddress-0.8.3/test/ipaddress/ipv4_test.rb +600 -0
  120. data/vendor/bundle/gems/ipaddress-0.8.3/test/ipaddress/ipv6_test.rb +426 -0
  121. data/vendor/bundle/gems/ipaddress-0.8.3/test/ipaddress/mongoid_test.rb +70 -0
  122. data/vendor/bundle/gems/ipaddress-0.8.3/test/ipaddress/prefix_test.rb +153 -0
  123. data/vendor/bundle/gems/ipaddress-0.8.3/test/ipaddress_test.rb +82 -0
  124. data/vendor/bundle/gems/ipaddress-0.8.3/test/test_helper.rb +35 -0
  125. data/vendor/bundle/gems/rspec-3.6.0/LICENSE.md +27 -0
  126. data/vendor/bundle/gems/rspec-3.6.0/README.md +39 -0
  127. data/vendor/bundle/gems/rspec-3.6.0/lib/rspec.rb +3 -0
  128. data/vendor/bundle/gems/rspec-3.6.0/lib/rspec/version.rb +5 -0
  129. data/vendor/bundle/gems/rspec-core-3.6.0/.document +5 -0
  130. data/vendor/bundle/gems/rspec-core-3.6.0/.yardopts +8 -0
  131. data/vendor/bundle/gems/rspec-core-3.6.0/Changelog.md +2167 -0
  132. data/vendor/bundle/gems/rspec-core-3.6.0/LICENSE.md +26 -0
  133. data/vendor/bundle/gems/rspec-core-3.6.0/README.md +384 -0
  134. data/vendor/bundle/gems/rspec-core-3.6.0/exe/rspec +4 -0
  135. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/autorun.rb +3 -0
  136. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core.rb +185 -0
  137. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/backtrace_formatter.rb +65 -0
  138. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/bisect/coordinator.rb +66 -0
  139. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/bisect/example_minimizer.rb +169 -0
  140. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/bisect/runner.rb +169 -0
  141. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/bisect/server.rb +70 -0
  142. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/configuration.rb +2177 -0
  143. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/configuration_options.rb +196 -0
  144. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/drb.rb +113 -0
  145. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/dsl.rb +98 -0
  146. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example.rb +653 -0
  147. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_group.rb +883 -0
  148. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/example_status_persister.rb +235 -0
  149. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/filter_manager.rb +231 -0
  150. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/flat_map.rb +20 -0
  151. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters.rb +265 -0
  152. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/base_formatter.rb +70 -0
  153. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/base_text_formatter.rb +75 -0
  154. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/bisect_formatter.rb +69 -0
  155. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/bisect_progress_formatter.rb +144 -0
  156. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/console_codes.rb +68 -0
  157. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/deprecation_formatter.rb +223 -0
  158. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/documentation_formatter.rb +70 -0
  159. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/exception_presenter.rb +496 -0
  160. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/fallback_message_formatter.rb +28 -0
  161. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/helpers.rb +110 -0
  162. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/html_formatter.rb +153 -0
  163. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/html_printer.rb +414 -0
  164. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/html_snippet_extractor.rb +118 -0
  165. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/json_formatter.rb +101 -0
  166. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/profile_formatter.rb +68 -0
  167. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/progress_formatter.rb +29 -0
  168. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/protocol.rb +182 -0
  169. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/snippet_extractor.rb +134 -0
  170. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/formatters/syntax_highlighter.rb +91 -0
  171. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/hooks.rb +624 -0
  172. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/invocations.rb +85 -0
  173. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/memoized_helpers.rb +535 -0
  174. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/metadata.rb +499 -0
  175. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/metadata_filter.rb +255 -0
  176. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/minitest_assertions_adapter.rb +31 -0
  177. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/mocking_adapters/flexmock.rb +31 -0
  178. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/mocking_adapters/mocha.rb +57 -0
  179. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/mocking_adapters/null.rb +14 -0
  180. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/mocking_adapters/rr.rb +31 -0
  181. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/mocking_adapters/rspec.rb +32 -0
  182. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/notifications.rb +514 -0
  183. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/option_parser.rb +309 -0
  184. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/ordering.rb +158 -0
  185. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/output_wrapper.rb +29 -0
  186. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/pending.rb +165 -0
  187. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/profiler.rb +32 -0
  188. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/project_initializer.rb +48 -0
  189. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/project_initializer/.rspec +1 -0
  190. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/project_initializer/spec/spec_helper.rb +100 -0
  191. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/rake_task.rb +168 -0
  192. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/reporter.rb +260 -0
  193. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/ruby_project.rb +53 -0
  194. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb +193 -0
  195. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/sandbox.rb +37 -0
  196. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/set.rb +54 -0
  197. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/shared_context.rb +55 -0
  198. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/shared_example_group.rb +271 -0
  199. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/shell_escape.rb +49 -0
  200. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/test_unit_assertions_adapter.rb +30 -0
  201. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/version.rb +9 -0
  202. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/warnings.rb +40 -0
  203. data/vendor/bundle/gems/rspec-core-3.6.0/lib/rspec/core/world.rb +264 -0
  204. data/vendor/bundle/gems/rspec-expectations-3.6.0/.document +5 -0
  205. data/vendor/bundle/gems/rspec-expectations-3.6.0/.yardopts +6 -0
  206. data/vendor/bundle/gems/rspec-expectations-3.6.0/Changelog.md +1072 -0
  207. data/vendor/bundle/gems/rspec-expectations-3.6.0/LICENSE.md +25 -0
  208. data/vendor/bundle/gems/rspec-expectations-3.6.0/README.md +305 -0
  209. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/expectations.rb +82 -0
  210. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/expectations/block_snippet_extractor.rb +253 -0
  211. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/expectations/configuration.rb +201 -0
  212. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/expectations/expectation_target.rb +127 -0
  213. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/expectations/fail_with.rb +39 -0
  214. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/expectations/failure_aggregator.rb +194 -0
  215. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/expectations/handler.rb +170 -0
  216. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/expectations/minitest_integration.rb +58 -0
  217. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/expectations/syntax.rb +132 -0
  218. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/expectations/version.rb +8 -0
  219. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers.rb +1025 -0
  220. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/aliased_matcher.rb +116 -0
  221. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in.rb +52 -0
  222. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/all.rb +85 -0
  223. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/base_matcher.rb +193 -0
  224. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/be.rb +288 -0
  225. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/be_between.rb +77 -0
  226. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/be_instance_of.rb +22 -0
  227. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/be_kind_of.rb +16 -0
  228. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/be_within.rb +72 -0
  229. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/change.rb +387 -0
  230. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/compound.rb +272 -0
  231. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/contain_exactly.rb +301 -0
  232. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/cover.rb +24 -0
  233. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/eq.rb +40 -0
  234. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/eql.rb +34 -0
  235. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/equal.rb +81 -0
  236. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/exist.rb +90 -0
  237. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/has.rb +103 -0
  238. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/have_attributes.rb +114 -0
  239. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/include.rb +143 -0
  240. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/match.rb +106 -0
  241. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/operators.rb +128 -0
  242. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/output.rb +200 -0
  243. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/raise_error.rb +230 -0
  244. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/respond_to.rb +165 -0
  245. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/satisfy.rb +60 -0
  246. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/start_or_end_with.rb +94 -0
  247. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/throw_symbol.rb +132 -0
  248. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/built_in/yield.rb +432 -0
  249. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/composable.rb +169 -0
  250. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/dsl.rb +527 -0
  251. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/english_phrasing.rb +58 -0
  252. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/expecteds_for_multiple_diffs.rb +73 -0
  253. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/fail_matchers.rb +42 -0
  254. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/generated_descriptions.rb +42 -0
  255. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/matcher_delegator.rb +35 -0
  256. data/vendor/bundle/gems/rspec-expectations-3.6.0/lib/rspec/matchers/matcher_protocol.rb +99 -0
  257. data/vendor/bundle/gems/rspec-mocks-3.6.0/.document +5 -0
  258. data/vendor/bundle/gems/rspec-mocks-3.6.0/.yardopts +6 -0
  259. data/vendor/bundle/gems/rspec-mocks-3.6.0/Changelog.md +1073 -0
  260. data/vendor/bundle/gems/rspec-mocks-3.6.0/LICENSE.md +25 -0
  261. data/vendor/bundle/gems/rspec-mocks-3.6.0/README.md +460 -0
  262. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks.rb +130 -0
  263. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/any_instance.rb +11 -0
  264. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/any_instance/chain.rb +110 -0
  265. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/any_instance/error_generator.rb +31 -0
  266. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/any_instance/expect_chain_chain.rb +31 -0
  267. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/any_instance/expectation_chain.rb +50 -0
  268. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/any_instance/message_chains.rb +83 -0
  269. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/any_instance/proxy.rb +116 -0
  270. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/any_instance/recorder.rb +289 -0
  271. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/any_instance/stub_chain.rb +51 -0
  272. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/any_instance/stub_chain_chain.rb +23 -0
  273. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/argument_list_matcher.rb +100 -0
  274. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/argument_matchers.rb +320 -0
  275. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/configuration.rb +212 -0
  276. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/error_generator.rb +369 -0
  277. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/example_methods.rb +434 -0
  278. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/instance_method_stasher.rb +146 -0
  279. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/marshal_extension.rb +41 -0
  280. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/matchers/expectation_customization.rb +20 -0
  281. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/matchers/have_received.rb +130 -0
  282. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/matchers/receive.rb +132 -0
  283. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/matchers/receive_message_chain.rb +82 -0
  284. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/matchers/receive_messages.rb +77 -0
  285. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/message_chain.rb +87 -0
  286. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/message_expectation.rb +740 -0
  287. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/method_double.rb +287 -0
  288. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/method_reference.rb +202 -0
  289. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/minitest_integration.rb +68 -0
  290. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/mutate_const.rb +339 -0
  291. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/object_reference.rb +149 -0
  292. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/order_group.rb +81 -0
  293. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/proxy.rb +484 -0
  294. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/space.rb +238 -0
  295. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/standalone.rb +3 -0
  296. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/syntax.rb +325 -0
  297. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/targets.rb +124 -0
  298. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/test_double.rb +171 -0
  299. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/verifying_double.rb +129 -0
  300. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/verifying_message_expectation.rb +54 -0
  301. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/verifying_proxy.rb +220 -0
  302. data/vendor/bundle/gems/rspec-mocks-3.6.0/lib/rspec/mocks/version.rb +9 -0
  303. data/vendor/bundle/gems/rspec-support-3.6.0/Changelog.md +211 -0
  304. data/vendor/bundle/gems/rspec-support-3.6.0/LICENSE.md +23 -0
  305. data/vendor/bundle/gems/rspec-support-3.6.0/README.md +40 -0
  306. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support.rb +139 -0
  307. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/caller_filter.rb +83 -0
  308. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/comparable_version.rb +46 -0
  309. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/differ.rb +215 -0
  310. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/directory_maker.rb +63 -0
  311. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/encoded_string.rb +165 -0
  312. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/fuzzy_matcher.rb +48 -0
  313. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/hunk_generator.rb +47 -0
  314. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/matcher_definition.rb +42 -0
  315. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/method_signature_verifier.rb +392 -0
  316. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/mutex.rb +73 -0
  317. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/object_formatter.rb +268 -0
  318. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/recursive_const_methods.rb +76 -0
  319. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/reentrant_mutex.rb +53 -0
  320. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/ruby_features.rb +162 -0
  321. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/source.rb +75 -0
  322. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/source/location.rb +21 -0
  323. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/source/node.rb +107 -0
  324. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/source/token.rb +87 -0
  325. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/spec.rb +81 -0
  326. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/spec/deprecation_helpers.rb +64 -0
  327. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/spec/formatting_support.rb +9 -0
  328. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/spec/in_sub_process.rb +69 -0
  329. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/spec/library_wide_checks.rb +150 -0
  330. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/spec/shell_out.rb +84 -0
  331. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/spec/stderr_splitter.rb +63 -0
  332. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/spec/string_matcher.rb +46 -0
  333. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/spec/with_isolated_directory.rb +13 -0
  334. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/spec/with_isolated_stderr.rb +13 -0
  335. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/version.rb +7 -0
  336. data/vendor/bundle/gems/rspec-support-3.6.0/lib/rspec/support/warnings.rb +39 -0
  337. data/vendor/bundle/specifications/diff-lcs-1.3.gemspec +61 -0
  338. data/vendor/bundle/specifications/echonet_lite-0.1.0.gemspec +43 -0
  339. data/vendor/bundle/specifications/ipaddr-1.0.0.gemspec +38 -0
  340. data/vendor/bundle/specifications/ipaddress-0.8.3.gemspec +35 -0
  341. data/vendor/bundle/specifications/rspec-3.6.0.gemspec +42 -0
  342. data/vendor/bundle/specifications/rspec-core-3.6.0.gemspec +62 -0
  343. data/vendor/bundle/specifications/rspec-expectations-3.6.0.gemspec +50 -0
  344. data/vendor/bundle/specifications/rspec-mocks-3.6.0.gemspec +50 -0
  345. data/vendor/bundle/specifications/rspec-support-3.6.0.gemspec +41 -0
  346. metadata +444 -0
@@ -0,0 +1,66 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require "bundler/gem_tasks"
5
+
6
+
7
+ require 'rake/testtask'
8
+ Rake::TestTask.new(:test) do |test|
9
+ test.libs << 'lib' << 'test'
10
+ test.pattern = 'test/**/*_test.rb'
11
+ test.verbose = true
12
+ end
13
+
14
+ begin
15
+ require 'rcov/rcovtask'
16
+ Rcov::RcovTask.new do |test|
17
+ test.libs << 'test'
18
+ test.pattern = 'test/**/*_test.rb'
19
+ test.verbose = true
20
+ end
21
+ rescue LoadError
22
+ task :rcov do
23
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
24
+ end
25
+ end
26
+
27
+
28
+ task :default => :test
29
+
30
+ require 'rdoc/task'
31
+ Rake::RDocTask.new do |rdoc|
32
+ if File.exist?('VERSION.yml')
33
+ config = YAML.load(File.read('VERSION.yml'))
34
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
35
+ else
36
+ version = ""
37
+ end
38
+
39
+ rdoc.rdoc_dir = 'rdoc'
40
+ rdoc.title = "ipaddress #{version}"
41
+ rdoc.rdoc_files.include('README*')
42
+ rdoc.rdoc_files.include('lib/**/*.rb')
43
+ end
44
+
45
+ desc "Open an irb session preloaded with this library"
46
+ task :console do
47
+ sh "irb -rubygems -I lib -r ipaddress.rb"
48
+ end
49
+
50
+ desc "Look for TODO and FIXME tags in the code"
51
+ task :todo do
52
+ def egrep(pattern)
53
+ Dir['**/*.rb'].each do |fn|
54
+ count = 0
55
+ open(fn) do |f|
56
+ while line = f.gets
57
+ count += 1
58
+ if line =~ pattern
59
+ puts "#{fn}:#{count}:#{line}"
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ egrep /(FIXME|TODO|TBD)/
66
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ipaddress/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ipaddress"
8
+ spec.version = Ipaddress::VERSION
9
+ spec.authors = ["bluemonk", "mikemackintosh"]
10
+ spec.email = ["ceresa@gmail.com"]
11
+ spec.summary = %q{IPv4/IPv6 address manipulation library}
12
+ spec.description = %q{IPAddress is a Ruby library designed to make manipulation
13
+ of IPv4 and IPv6 addresses both powerful and simple. It mantains
14
+ a layer of compatibility with Ruby's own IPAddr, while
15
+ addressing many of its issues.}
16
+ spec.homepage = "https://github.com/bluemonk/ipaddress"
17
+ spec.license = "MIT"
18
+
19
+ spec.files = `git ls-files -z`.split("\x0")
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler"
25
+ spec.add_development_dependency "rake"
26
+ end
@@ -0,0 +1,227 @@
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
+
15
+ require 'ipaddress/ipv4'
16
+ require 'ipaddress/ipv6'
17
+ require 'ipaddress/mongoid' if defined?(Mongoid)
18
+
19
+ module IPAddress
20
+
21
+ NAME = "IPAddress"
22
+ GEM = "ipaddress"
23
+ AUTHORS = ["Marco Ceresa <ceresa@ieee.org>"]
24
+
25
+ #
26
+ # Parse the argument string to create a new
27
+ # IPv4, IPv6 or Mapped IP object
28
+ #
29
+ # ip = IPAddress.parse 167837953 # 10.1.1.1
30
+ # ip = IPAddress.parse "172.16.10.1/24"
31
+ # ip6 = IPAddress.parse "2001:db8::8:800:200c:417a/64"
32
+ # ip_mapped = IPAddress.parse "::ffff:172.16.10.1/128"
33
+ #
34
+ # All the object created will be instances of the
35
+ # correct class:
36
+ #
37
+ # ip.class
38
+ # #=> IPAddress::IPv4
39
+ # ip6.class
40
+ # #=> IPAddress::IPv6
41
+ # ip_mapped.class
42
+ # #=> IPAddress::IPv6::Mapped
43
+ #
44
+ def IPAddress::parse(str)
45
+
46
+ # Check if an int was passed
47
+ if str.kind_of? Integer
48
+ return IPAddress::IPv4.new(ntoa(str))
49
+ end
50
+
51
+ case str
52
+ when /:.+\./
53
+ IPAddress::IPv6::Mapped.new(str)
54
+ when /\./
55
+ IPAddress::IPv4.new(str)
56
+ when /:/
57
+ IPAddress::IPv6.new(str)
58
+ else
59
+ raise ArgumentError, "Unknown IP Address #{str}"
60
+ end
61
+ end
62
+
63
+ #
64
+ # Converts a unit32 to IPv4
65
+ #
66
+ # IPAddress::ntoa(167837953)
67
+ # #-> "10.1.1.1"
68
+ #
69
+ def self.ntoa(uint)
70
+ unless(uint.is_a? Numeric and uint <= 0xffffffff and uint >= 0)
71
+ raise(::ArgumentError, "not a long integer: #{uint.inspect}")
72
+ end
73
+ ret = []
74
+ 4.times do
75
+ ret.unshift(uint & 0xff)
76
+ uint >>= 8
77
+ end
78
+ ret.join('.')
79
+ end
80
+
81
+ #
82
+ # True if the object is an IPv4 address
83
+ #
84
+ # ip = IPAddress("192.168.10.100/24")
85
+ #
86
+ # ip.ipv4?
87
+ # #-> true
88
+ #
89
+ def ipv4?
90
+ self.kind_of? IPAddress::IPv4
91
+ end
92
+
93
+ #
94
+ # True if the object is an IPv6 address
95
+ #
96
+ # ip = IPAddress("192.168.10.100/24")
97
+ #
98
+ # ip.ipv6?
99
+ # #-> false
100
+ #
101
+ def ipv6?
102
+ self.kind_of? IPAddress::IPv6
103
+ end
104
+
105
+ #
106
+ # Checks if the given string is a valid IP address,
107
+ # either IPv4 or IPv6
108
+ #
109
+ # Example:
110
+ #
111
+ # IPAddress::valid? "2002::1"
112
+ # #=> true
113
+ #
114
+ # IPAddress::valid? "10.0.0.256"
115
+ # #=> false
116
+ #
117
+ def self.valid?(addr)
118
+ valid_ipv4?(addr) || valid_ipv6?(addr)
119
+ end
120
+
121
+ #
122
+ # Checks if the given string is a valid IPv4 address
123
+ #
124
+ # Example:
125
+ #
126
+ # IPAddress::valid_ipv4? "2002::1"
127
+ # #=> false
128
+ #
129
+ # IPAddress::valid_ipv4? "172.16.10.1"
130
+ # #=> true
131
+ #
132
+ def self.valid_ipv4?(addr)
133
+ if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr
134
+ return $~.captures.all? {|i| i.to_i < 256}
135
+ end
136
+ false
137
+ end
138
+
139
+ #
140
+ # Checks if the argument is a valid IPv4 netmask
141
+ # expressed in dotted decimal format.
142
+ #
143
+ # IPAddress.valid_ipv4_netmask? "255.255.0.0"
144
+ # #=> true
145
+ #
146
+ def self.valid_ipv4_netmask?(addr)
147
+ arr = addr.split(".").map{|i| i.to_i}.pack("CCCC").unpack("B*").first.scan(/01/)
148
+ arr.empty? && valid_ipv4?(addr)
149
+ rescue
150
+ return false
151
+ end
152
+
153
+ #
154
+ # Checks if the given string is a valid IPv6 address
155
+ #
156
+ # Example:
157
+ #
158
+ # IPAddress::valid_ipv6? "2002::1"
159
+ # #=> true
160
+ #
161
+ # IPAddress::valid_ipv6? "2002::DEAD::BEEF"
162
+ # #=> false
163
+ #
164
+ def self.valid_ipv6?(addr)
165
+ # https://gist.github.com/cpetschnig/294476
166
+ # http://forums.intermapper.com/viewtopic.php?t=452
167
+ 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
168
+ false
169
+ end
170
+
171
+ #
172
+ # Deprecate method
173
+ #
174
+ def self.deprecate(message = nil) # :nodoc:
175
+ message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
176
+ warn("DEPRECATION WARNING: #{message}")
177
+ end
178
+
179
+ end # module IPAddress
180
+
181
+ #
182
+ # IPAddress is a wrapper method built around
183
+ # IPAddress's library classes. Its purpouse is to
184
+ # make you indipendent from the type of IP address
185
+ # you're going to use.
186
+ #
187
+ # For example, instead of creating the three types
188
+ # of IP addresses using their own contructors
189
+ #
190
+ # ip = IPAddress::IPv4.new "172.16.10.1/24"
191
+ # ip6 = IPAddress::IPv6.new "2001:db8::8:800:200c:417a/64"
192
+ # ip_mapped = IPAddress::IPv6::Mapped "::ffff:172.16.10.1/128"
193
+ #
194
+ # you can just use the IPAddress wrapper:
195
+ #
196
+ # ip = IPAddress "172.16.10.1/24"
197
+ # ip6 = IPAddress "2001:db8::8:800:200c:417a/64"
198
+ # ip_mapped = IPAddress "::ffff:172.16.10.1/128"
199
+ #
200
+ # All the object created will be instances of the
201
+ # correct class:
202
+ #
203
+ # ip.class
204
+ # #=> IPAddress::IPv4
205
+ # ip6.class
206
+ # #=> IPAddress::IPv6
207
+ # ip_mapped.class
208
+ # #=> IPAddress::IPv6::Mapped
209
+ #
210
+ def IPAddress(str)
211
+ IPAddress::parse str
212
+ end
213
+
214
+ #
215
+ # Compatibility with Ruby 1.8
216
+ #
217
+ if RUBY_VERSION =~ /^1\.8/
218
+ class Hash # :nodoc:
219
+ alias :key :index
220
+ end
221
+ module Math # :nodoc:
222
+ def Math.log2(n)
223
+ log(n) / log(2)
224
+ end
225
+ end
226
+ end
227
+
@@ -0,0 +1,1114 @@
1
+ require 'ipaddress/prefix'
2
+
3
+ module IPAddress;
4
+ #
5
+ # =Name
6
+ #
7
+ # IPAddress::IPv4 - IP version 4 address manipulation library
8
+ #
9
+ # =Synopsis
10
+ #
11
+ # require 'ipaddress'
12
+ #
13
+ # =Description
14
+ #
15
+ # Class IPAddress::IPv4 is used to handle IPv4 type addresses.
16
+ #
17
+ class IPv4
18
+
19
+ include IPAddress
20
+ include Enumerable
21
+ include Comparable
22
+
23
+ #
24
+ # This Hash contains the prefix values for Classful networks
25
+ #
26
+ # Note that classes C, D and E will all have a default
27
+ # prefix of /24 or 255.255.255.0
28
+ #
29
+ CLASSFUL = {
30
+ /^0../ => 8, # Class A, from 0.0.0.0 to 127.255.255.255
31
+ /^10./ => 16, # Class B, from 128.0.0.0 to 191.255.255.255
32
+ /^110/ => 24 # Class C, D and E, from 192.0.0.0 to 255.255.255.254
33
+ }
34
+
35
+ #
36
+ # Regular expression to match an IPv4 address
37
+ #
38
+ REGEXP = Regexp.new(/((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)/)
39
+
40
+ #
41
+ # Creates a new IPv4 address object.
42
+ #
43
+ # An IPv4 address can be expressed in any of the following forms:
44
+ #
45
+ # * "10.1.1.1/24": ip +address+ and +prefix+. This is the common and
46
+ # suggested way to create an object .
47
+ # * "10.1.1.1/255.255.255.0": ip +address+ and +netmask+. Although
48
+ # convenient sometimes, this format is less clear than the previous
49
+ # one.
50
+ # * "10.1.1.1": if the address alone is specified, the prefix will be
51
+ # set as default 32, also known as the host prefix
52
+ #
53
+ # Examples:
54
+ #
55
+ # # These two are the same
56
+ # ip = IPAddress::IPv4.new("10.0.0.1/24")
57
+ # ip = IPAddress("10.0.0.1/24")
58
+ #
59
+ # # These two are the same
60
+ # IPAddress::IPv4.new "10.0.0.1/8"
61
+ # IPAddress::IPv4.new "10.0.0.1/255.0.0.0"
62
+ #
63
+ def initialize(str)
64
+ ip, netmask = str.split("/")
65
+
66
+ # Check the ip and remove white space
67
+ if IPAddress.valid_ipv4?(ip)
68
+ @address = ip.strip
69
+ else
70
+ raise ArgumentError, "Invalid IP #{ip.inspect}"
71
+ end
72
+
73
+ # Check the netmask
74
+ if netmask # netmask is defined
75
+ netmask.strip!
76
+ if netmask =~ /^\d{1,2}$/ # netmask in cidr format
77
+ @prefix = Prefix32.new(netmask.to_i)
78
+ elsif IPAddress.valid_ipv4_netmask?(netmask) # netmask in IP format
79
+ @prefix = Prefix32.parse_netmask(netmask)
80
+ else # invalid netmask
81
+ raise ArgumentError, "Invalid netmask #{netmask}"
82
+ end
83
+ else # netmask is nil, reverting to defaul classful mask
84
+ @prefix = Prefix32.new(32)
85
+ end
86
+
87
+ # Array formed with the IP octets
88
+ @octets = @address.split(".").map{|i| i.to_i}
89
+ # 32 bits interger containing the address
90
+ @u32 = (@octets[0]<< 24) + (@octets[1]<< 16) + (@octets[2]<< 8) + (@octets[3])
91
+
92
+ end # def initialize
93
+
94
+ #
95
+ # Returns the address portion of the IPv4 object
96
+ # as a string.
97
+ #
98
+ # ip = IPAddress("172.16.100.4/22")
99
+ #
100
+ # ip.address
101
+ # #=> "172.16.100.4"
102
+ #
103
+ def address
104
+ @address
105
+ end
106
+
107
+ #
108
+ # Returns the prefix portion of the IPv4 object
109
+ # as a IPAddress::Prefix32 object
110
+ #
111
+ # ip = IPAddress("172.16.100.4/22")
112
+ #
113
+ # ip.prefix
114
+ # #=> 22
115
+ #
116
+ # ip.prefix.class
117
+ # #=> IPAddress::Prefix32
118
+ #
119
+ def prefix
120
+ @prefix
121
+ end
122
+
123
+ #
124
+ # Set a new prefix number for the object
125
+ #
126
+ # This is useful if you want to change the prefix
127
+ # to an object created with IPv4::parse_u32 or
128
+ # if the object was created using the classful
129
+ # mask.
130
+ #
131
+ # ip = IPAddress("172.16.100.4")
132
+ #
133
+ # puts ip
134
+ # #=> 172.16.100.4/16
135
+ #
136
+ # ip.prefix = 22
137
+ #
138
+ # puts ip
139
+ # #=> 172.16.100.4/22
140
+ #
141
+ def prefix=(num)
142
+ @prefix = Prefix32.new(num)
143
+ end
144
+
145
+ #
146
+ # Returns the address as an array of decimal values
147
+ #
148
+ # ip = IPAddress("172.16.100.4")
149
+ #
150
+ # ip.octets
151
+ # #=> [172, 16, 100, 4]
152
+ #
153
+ def octets
154
+ @octets
155
+ end
156
+
157
+ #
158
+ # Returns a string with the address portion of
159
+ # the IPv4 object
160
+ #
161
+ # ip = IPAddress("172.16.100.4/22")
162
+ #
163
+ # ip.to_s
164
+ # #=> "172.16.100.4"
165
+ #
166
+ def to_s
167
+ @address
168
+ end
169
+
170
+ #
171
+ # Returns a string with the IP address in canonical
172
+ # form.
173
+ #
174
+ # ip = IPAddress("172.16.100.4/22")
175
+ #
176
+ # ip.to_string
177
+ # #=> "172.16.100.4/22"
178
+ #
179
+ def to_string
180
+ "#@address/#@prefix"
181
+ end
182
+
183
+ #
184
+ # Returns the prefix as a string in IP format
185
+ #
186
+ # ip = IPAddress("172.16.100.4/22")
187
+ #
188
+ # ip.netmask
189
+ # #=> "255.255.252.0"
190
+ #
191
+ def netmask
192
+ @prefix.to_ip
193
+ end
194
+
195
+ #
196
+ # Like IPv4#prefix=, this method allow you to
197
+ # change the prefix / netmask of an IP address
198
+ # object.
199
+ #
200
+ # ip = IPAddress("172.16.100.4")
201
+ #
202
+ # puts ip
203
+ # #=> 172.16.100.4/16
204
+ #
205
+ # ip.netmask = "255.255.252.0"
206
+ #
207
+ # puts ip
208
+ # #=> 172.16.100.4/22
209
+ #
210
+ def netmask=(addr)
211
+ @prefix = Prefix32.parse_netmask(addr)
212
+ end
213
+
214
+ #
215
+ # Returns the address portion in unsigned
216
+ # 32 bits integer format.
217
+ #
218
+ # This method is identical to the C function
219
+ # inet_pton to create a 32 bits address family
220
+ # structure.
221
+ #
222
+ # ip = IPAddress("10.0.0.0/8")
223
+ #
224
+ # ip.to_i
225
+ # #=> 167772160
226
+ #
227
+ def u32
228
+ @u32
229
+ end
230
+ alias_method :to_i, :u32
231
+ alias_method :to_u32, :u32
232
+
233
+ #
234
+ # Returns the address portion in
235
+ # hex
236
+ #
237
+ # ip = IPAddress("10.0.0.0")
238
+ #
239
+ # ip.to_h
240
+ # #=> 0a000000
241
+ #
242
+ def hex(space=true)
243
+ "%.4x%.4x" % [to_u32].pack("N").unpack("nn")
244
+ end
245
+ alias_method :to_h, :hex
246
+ alias_method :to_hex, :hex
247
+
248
+ #
249
+ # Returns the address portion of an IPv4 object
250
+ # in a network byte order format.
251
+ #
252
+ # ip = IPAddress("172.16.10.1/24")
253
+ #
254
+ # ip.data
255
+ # #=> "\254\020\n\001"
256
+ #
257
+ # It is usually used to include an IP address
258
+ # in a data packet to be sent over a socket
259
+ #
260
+ # a = Socket.open(params) # socket details here
261
+ # ip = IPAddress("10.1.1.0/24")
262
+ # binary_data = ["Address: "].pack("a*") + ip.data
263
+ #
264
+ # # Send binary data
265
+ # a.puts binary_data
266
+ #
267
+ def data
268
+ [@u32].pack("N")
269
+ end
270
+
271
+ #
272
+ # Returns the octet specified by index
273
+ #
274
+ # ip = IPAddress("172.16.100.50/24")
275
+ #
276
+ # ip[0]
277
+ # #=> 172
278
+ # ip[1]
279
+ # #=> 16
280
+ # ip[2]
281
+ # #=> 100
282
+ # ip[3]
283
+ # #=> 50
284
+ #
285
+ def [](index)
286
+ @octets[index]
287
+ end
288
+ alias_method :octet, :[]
289
+
290
+ #
291
+ # Updated the octet specified at index
292
+ #
293
+ # ip = IPAddress("172.16.100.50/24")
294
+ # ip[2] = 200
295
+ #
296
+ # #=> #<IPAddress::IPv4:0x00000000000000 @address="172.16.200.1",
297
+ # #=> @prefix=32, @octets=[172, 16, 200, 1], @u32=2886780929>
298
+ #
299
+ def []=(index, value)
300
+ @octets[index] = value.to_i
301
+ initialize("#{@octets.join('.')}/#{prefix}")
302
+ end
303
+ alias_method :octet=, :[]=
304
+
305
+ #
306
+ # Returns the address portion of an IP in binary format,
307
+ # as a string containing a sequence of 0 and 1
308
+ #
309
+ # ip = IPAddress("127.0.0.1")
310
+ #
311
+ # ip.bits
312
+ # #=> "01111111000000000000000000000001"
313
+ #
314
+ def bits
315
+ data.unpack("B*").first
316
+ end
317
+
318
+ #
319
+ # Returns the broadcast address for the given IP.
320
+ #
321
+ # ip = IPAddress("172.16.10.64/24")
322
+ #
323
+ # ip.broadcast.to_s
324
+ # #=> "172.16.10.255"
325
+ #
326
+ def broadcast
327
+ case
328
+ when prefix <= 30
329
+ self.class.parse_u32(broadcast_u32, @prefix)
330
+ when prefix == 31
331
+ self.class.parse_u32(-1, @prefix)
332
+ when prefix == 32
333
+ return self
334
+ end
335
+ end
336
+
337
+ #
338
+ # Checks if the IP address is actually a network
339
+ #
340
+ # ip = IPAddress("172.16.10.64/24")
341
+ #
342
+ # ip.network?
343
+ # #=> false
344
+ #
345
+ # ip = IPAddress("172.16.10.64/26")
346
+ #
347
+ # ip.network?
348
+ # #=> true
349
+ #
350
+ def network?
351
+ (@prefix < 32) && (@u32 | @prefix.to_u32 == @prefix.to_u32)
352
+ end
353
+
354
+ #
355
+ # Returns a new IPv4 object with the network number
356
+ # for the given IP.
357
+ #
358
+ # ip = IPAddress("172.16.10.64/24")
359
+ #
360
+ # ip.network.to_s
361
+ # #=> "172.16.10.0"
362
+ #
363
+ def network
364
+ self.class.parse_u32(network_u32, @prefix)
365
+ end
366
+
367
+ #
368
+ # Returns a new IPv4 object with the
369
+ # first host IP address in the range.
370
+ #
371
+ # Example: given the 192.168.100.0/24 network, the first
372
+ # host IP address is 192.168.100.1.
373
+ #
374
+ # ip = IPAddress("192.168.100.0/24")
375
+ #
376
+ # ip.first.to_s
377
+ # #=> "192.168.100.1"
378
+ #
379
+ # The object IP doesn't need to be a network: the method
380
+ # automatically gets the network number from it
381
+ #
382
+ # ip = IPAddress("192.168.100.50/24")
383
+ #
384
+ # ip.first.to_s
385
+ # #=> "192.168.100.1"
386
+ #
387
+ def first
388
+ case
389
+ when prefix <= 30
390
+ self.class.parse_u32(network_u32+1, @prefix)
391
+ when prefix == 31
392
+ self.class.parse_u32(network_u32, @prefix)
393
+ when prefix == 32
394
+ return self
395
+ end
396
+ end
397
+
398
+ #
399
+ # Like its sibling method IPv4#first, this method
400
+ # returns a new IPv4 object with the
401
+ # last host IP address in the range.
402
+ #
403
+ # Example: given the 192.168.100.0/24 network, the last
404
+ # host IP address is 192.168.100.254
405
+ #
406
+ # ip = IPAddress("192.168.100.0/24")
407
+ #
408
+ # ip.last.to_s
409
+ # #=> "192.168.100.254"
410
+ #
411
+ # The object IP doesn't need to be a network: the method
412
+ # automatically gets the network number from it
413
+ #
414
+ # ip = IPAddress("192.168.100.50/24")
415
+ #
416
+ # ip.last.to_s
417
+ # #=> "192.168.100.254"
418
+ #
419
+ def last
420
+ case
421
+ when prefix <= 30
422
+ self.class.parse_u32(broadcast_u32-1, @prefix)
423
+ when prefix == 31
424
+ self.class.parse_u32(broadcast_u32, @prefix)
425
+ when prefix == 32
426
+ return self
427
+ end
428
+ end
429
+
430
+ #
431
+ # Iterates over all the hosts IP addresses for the given
432
+ # network (or IP address).
433
+ #
434
+ # ip = IPAddress("10.0.0.1/29")
435
+ #
436
+ # ip.each_host do |i|
437
+ # p i.to_s
438
+ # end
439
+ # #=> "10.0.0.1"
440
+ # #=> "10.0.0.2"
441
+ # #=> "10.0.0.3"
442
+ # #=> "10.0.0.4"
443
+ # #=> "10.0.0.5"
444
+ # #=> "10.0.0.6"
445
+ #
446
+ def each_host
447
+ (network_u32+1..broadcast_u32-1).each do |i|
448
+ yield self.class.parse_u32(i, @prefix)
449
+ end
450
+ end
451
+
452
+ #
453
+ # Iterates over all the IP addresses for the given
454
+ # network (or IP address).
455
+ #
456
+ # The object yielded is a new IPv4 object created
457
+ # from the iteration.
458
+ #
459
+ # ip = IPAddress("10.0.0.1/29")
460
+ #
461
+ # ip.each do |i|
462
+ # p i.address
463
+ # end
464
+ # #=> "10.0.0.0"
465
+ # #=> "10.0.0.1"
466
+ # #=> "10.0.0.2"
467
+ # #=> "10.0.0.3"
468
+ # #=> "10.0.0.4"
469
+ # #=> "10.0.0.5"
470
+ # #=> "10.0.0.6"
471
+ # #=> "10.0.0.7"
472
+ #
473
+ def each
474
+ (network_u32..broadcast_u32).each do |i|
475
+ yield self.class.parse_u32(i, @prefix)
476
+ end
477
+ end
478
+
479
+ #
480
+ # Spaceship operator to compare IPv4 objects
481
+ #
482
+ # Comparing IPv4 addresses is useful to ordinate
483
+ # them into lists that match our intuitive
484
+ # perception of ordered IP addresses.
485
+ #
486
+ # The first comparison criteria is the u32 value.
487
+ # For example, 10.100.100.1 will be considered
488
+ # to be less than 172.16.0.1, because, in a ordered list,
489
+ # we expect 10.100.100.1 to come before 172.16.0.1.
490
+ #
491
+ # The second criteria, in case two IPv4 objects
492
+ # have identical addresses, is the prefix. An higher
493
+ # prefix will be considered greater than a lower
494
+ # prefix. This is because we expect to see
495
+ # 10.100.100.0/24 come before 10.100.100.0/25.
496
+ #
497
+ # Example:
498
+ #
499
+ # ip1 = IPAddress "10.100.100.1/8"
500
+ # ip2 = IPAddress "172.16.0.1/16"
501
+ # ip3 = IPAddress "10.100.100.1/16"
502
+ #
503
+ # ip1 < ip2
504
+ # #=> true
505
+ # ip1 > ip3
506
+ # #=> false
507
+ #
508
+ # [ip1,ip2,ip3].sort.map{|i| i.to_string}
509
+ # #=> ["10.100.100.1/8","10.100.100.1/16","172.16.0.1/16"]
510
+ #
511
+ def <=>(oth)
512
+ return prefix <=> oth.prefix if to_u32 == oth.to_u32
513
+ to_u32 <=> oth.to_u32
514
+ end
515
+
516
+ #
517
+ # Returns the number of IP addresses included
518
+ # in the network. It also counts the network
519
+ # address and the broadcast address.
520
+ #
521
+ # ip = IPAddress("10.0.0.1/29")
522
+ #
523
+ # ip.size
524
+ # #=> 8
525
+ #
526
+ def size
527
+ 2 ** @prefix.host_prefix
528
+ end
529
+
530
+ #
531
+ # Returns an array with the IP addresses of
532
+ # all the hosts in the network.
533
+ #
534
+ # ip = IPAddress("10.0.0.1/29")
535
+ #
536
+ # ip.hosts.map {|i| i.address}
537
+ # #=> ["10.0.0.1",
538
+ # #=> "10.0.0.2",
539
+ # #=> "10.0.0.3",
540
+ # #=> "10.0.0.4",
541
+ # #=> "10.0.0.5",
542
+ # #=> "10.0.0.6"]
543
+ #
544
+ def hosts
545
+ to_a[1..-2]
546
+ end
547
+
548
+ #
549
+ # Returns the network number in Unsigned 32bits format
550
+ #
551
+ # ip = IPAddress("10.0.0.1/29")
552
+ #
553
+ # ip.network_u32
554
+ # #=> 167772160
555
+ #
556
+ def network_u32
557
+ @u32 & @prefix.to_u32
558
+ end
559
+
560
+ #
561
+ # Returns the broadcast address in Unsigned 32bits format
562
+ #
563
+ # ip = IPaddress("10.0.0.1/29")
564
+ #
565
+ # ip.broadcast_u32
566
+ # #=> 167772167
567
+ #
568
+ def broadcast_u32
569
+ network_u32 + size - 1
570
+ end
571
+
572
+ #
573
+ # Checks whether a subnet includes the given IP address.
574
+ #
575
+ # Accepts an IPAddress::IPv4 object.
576
+ #
577
+ # ip = IPAddress("192.168.10.100/24")
578
+ #
579
+ # addr = IPAddress("192.168.10.102/24")
580
+ #
581
+ # ip.include? addr
582
+ # #=> true
583
+ #
584
+ # ip.include? IPAddress("172.16.0.48/16")
585
+ # #=> false
586
+ #
587
+ def include?(oth)
588
+ @prefix <= oth.prefix and network_u32 == (oth.to_u32 & @prefix.to_u32)
589
+ end
590
+
591
+ #
592
+ # Checks whether a subnet includes all the
593
+ # given IPv4 objects.
594
+ #
595
+ # ip = IPAddress("192.168.10.100/24")
596
+ #
597
+ # addr1 = IPAddress("192.168.10.102/24")
598
+ # addr2 = IPAddress("192.168.10.103/24")
599
+ #
600
+ # ip.include_all?(addr1,addr2)
601
+ # #=> true
602
+ #
603
+ def include_all?(*others)
604
+ others.all? {|oth| include?(oth)}
605
+ end
606
+
607
+ #
608
+ # Checks if an IPv4 address objects belongs
609
+ # to a private network RFC1918
610
+ #
611
+ # Example:
612
+ #
613
+ # ip = IPAddress "10.1.1.1/24"
614
+ # ip.private?
615
+ # #=> true
616
+ #
617
+ def private?
618
+ [self.class.new("10.0.0.0/8"),
619
+ self.class.new("172.16.0.0/12"),
620
+ self.class.new("192.168.0.0/16")].any? {|i| i.include? self}
621
+ end
622
+
623
+ #
624
+ # Checks if an IPv4 address objects belongs
625
+ # to a multicast network RFC3171
626
+ #
627
+ # Example:
628
+ #
629
+ # ip = IPAddress "224.0.0.0/4"
630
+ # ip.multicast?
631
+ # #=> true
632
+ #
633
+ def multicast?
634
+ [self.class.new("224.0.0.0/4")].any? {|i| i.include? self}
635
+ end
636
+
637
+ #
638
+ # Checks if an IPv4 address objects belongs
639
+ # to a multicast network RFC3171
640
+ #
641
+ # Example:
642
+ #
643
+ # ip = IPAddress "224.0.0.0/4"
644
+ # ip.multicast?
645
+ # #=> true
646
+ #
647
+ def multicast?
648
+ [self.class.new("224.0.0.0/4")].any? {|i| i.include? self}
649
+ end
650
+
651
+ #
652
+ # Checks if an IPv4 address objects belongs
653
+ # to a loopback network RFC1122
654
+ #
655
+ # Example:
656
+ #
657
+ # ip = IPAddress "127.0.0.1"
658
+ # ip.loopback?
659
+ # #=> true
660
+ #
661
+ def loopback?
662
+ [self.class.new("127.0.0.0/8")].any? {|i| i.include? self}
663
+ end
664
+
665
+ #
666
+ # Returns the IP address in in-addr.arpa format
667
+ # for DNS lookups
668
+ #
669
+ # ip = IPAddress("172.16.100.50/24")
670
+ #
671
+ # ip.reverse
672
+ # #=> "50.100.16.172.in-addr.arpa"
673
+ #
674
+ def reverse
675
+ @octets.reverse.join(".") + ".in-addr.arpa"
676
+ end
677
+ alias_method :arpa, :reverse
678
+
679
+ #
680
+ # Return a list of IP's between @address
681
+ # and the supplied IP
682
+ #
683
+ # ip = IPAddress("172.16.100.51/32")
684
+ #
685
+ # ip.to("172.16.100.100")
686
+ # #=> ["172.16.100.51",
687
+ # #=> "172.16.100.52",
688
+ # #=> ...
689
+ # #=> "172.16.100.99",
690
+ # #=> "172.16.100.100"]
691
+ #
692
+ def to(e)
693
+ unless e.is_a? IPAddress::IPv4
694
+ e = IPv4.new(e)
695
+ end
696
+
697
+ Range.new(@u32, e.to_u32).map{|i| IPAddress.ntoa(i) }
698
+ end
699
+ #
700
+ # Splits a network into different subnets
701
+ #
702
+ # If the IP Address is a network, it can be divided into
703
+ # multiple networks. If +self+ is not a network, this
704
+ # method will calculate the network from the IP and then
705
+ # subnet it.
706
+ #
707
+ # If +subnets+ is an power of two number, the resulting
708
+ # networks will be divided evenly from the supernet.
709
+ #
710
+ # network = IPAddress("172.16.10.0/24")
711
+ #
712
+ # network / 4 # implies map{|i| i.to_string}
713
+ # #=> ["172.16.10.0/26",
714
+ # #=> "172.16.10.64/26",
715
+ # #=> "172.16.10.128/26",
716
+ # #=> "172.16.10.192/26"]
717
+ #
718
+ # If +num+ is any other number, the supernet will be
719
+ # divided into some networks with a even number of hosts and
720
+ # other networks with the remaining addresses.
721
+ #
722
+ # network = IPAddress("172.16.10.0/24")
723
+ #
724
+ # network / 3 # implies map{|i| i.to_string}
725
+ # #=> ["172.16.10.0/26",
726
+ # #=> "172.16.10.64/26",
727
+ # #=> "172.16.10.128/25"]
728
+ #
729
+ # Returns an array of IPv4 objects
730
+ #
731
+ def split(subnets=2)
732
+ unless (1..(2**@prefix.host_prefix)).include? subnets
733
+ raise ArgumentError, "Value #{subnets} out of range"
734
+ end
735
+ networks = subnet(newprefix(subnets))
736
+ until networks.size == subnets
737
+ networks = sum_first_found(networks)
738
+ end
739
+ return networks
740
+ end
741
+ alias_method :/, :split
742
+
743
+ #
744
+ # Returns a new IPv4 object from the supernetting
745
+ # of the instance network.
746
+ #
747
+ # Supernetting is similar to subnetting, except
748
+ # that you getting as a result a network with a
749
+ # smaller prefix (bigger host space). For example,
750
+ # given the network
751
+ #
752
+ # ip = IPAddress("172.16.10.0/24")
753
+ #
754
+ # you can supernet it with a new /23 prefix
755
+ #
756
+ # ip.supernet(23).to_string
757
+ # #=> "172.16.10.0/23"
758
+ #
759
+ # However if you supernet it with a /22 prefix, the
760
+ # network address will change:
761
+ #
762
+ # ip.supernet(22).to_string
763
+ # #=> "172.16.8.0/22"
764
+ #
765
+ # If +new_prefix+ is less than 1, returns 0.0.0.0/0
766
+ #
767
+ def supernet(new_prefix)
768
+ raise ArgumentError, "New prefix must be smaller than existing prefix" if new_prefix >= @prefix.to_i
769
+ return self.class.new("0.0.0.0/0") if new_prefix < 1
770
+ return self.class.new(@address+"/#{new_prefix}").network
771
+ end
772
+
773
+ #
774
+ # This method implements the subnetting function
775
+ # similar to the one described in RFC3531.
776
+ #
777
+ # By specifying a new prefix, the method calculates
778
+ # the network number for the given IPv4 object
779
+ # and calculates the subnets associated to the new
780
+ # prefix.
781
+ #
782
+ # For example, given the following network:
783
+ #
784
+ # ip = IPAddress "172.16.10.0/24"
785
+ #
786
+ # we can calculate the subnets with a /26 prefix
787
+ #
788
+ # ip.subnets(26).map{&:to_string)
789
+ # #=> ["172.16.10.0/26", "172.16.10.64/26",
790
+ # "172.16.10.128/26", "172.16.10.192/26"]
791
+ #
792
+ # The resulting number of subnets will of course always be
793
+ # a power of two.
794
+ #
795
+ def subnet(subprefix)
796
+ unless ((@prefix.to_i)..32).include? subprefix
797
+ raise ArgumentError, "New prefix must be between #@prefix and 32"
798
+ end
799
+ Array.new(2**(subprefix-@prefix.to_i)) do |i|
800
+ self.class.parse_u32(network_u32+(i*(2**(32-subprefix))), subprefix)
801
+ end
802
+ end
803
+
804
+ #
805
+ # Returns the difference between two IP addresses
806
+ # in unsigned int 32 bits format
807
+ #
808
+ # Example:
809
+ #
810
+ # ip1 = IPAddress("172.16.10.0/24")
811
+ # ip2 = IPAddress("172.16.11.0/24")
812
+ #
813
+ # puts ip1 - ip2
814
+ # #=> 256
815
+ #
816
+ def -(oth)
817
+ return (to_u32 - oth.to_u32).abs
818
+ end
819
+
820
+ #
821
+ # Returns a new IPv4 object which is the result
822
+ # of the summarization, if possible, of the two
823
+ # objects
824
+ #
825
+ # Example:
826
+ #
827
+ # ip1 = IPAddress("172.16.10.1/24")
828
+ # ip2 = IPAddress("172.16.11.2/24")
829
+ #
830
+ # p (ip1 + ip2).map {|i| i.to_string}
831
+ # #=> ["172.16.10.0/23"]
832
+ #
833
+ # If the networks are not contiguous, returns
834
+ # the two network numbers from the objects
835
+ #
836
+ # ip1 = IPAddress("10.0.0.1/24")
837
+ # ip2 = IPAddress("10.0.2.1/24")
838
+ #
839
+ # p (ip1 + ip2).map {|i| i.to_string}
840
+ # #=> ["10.0.0.0/24","10.0.2.0/24"]
841
+ #
842
+ def +(oth)
843
+ aggregate(*[self,oth].sort.map{|i| i.network})
844
+ end
845
+
846
+ #
847
+ # Checks whether the ip address belongs to a
848
+ # RFC 791 CLASS A network, no matter
849
+ # what the subnet mask is.
850
+ #
851
+ # Example:
852
+ #
853
+ # ip = IPAddress("10.0.0.1/24")
854
+ #
855
+ # ip.a?
856
+ # #=> true
857
+ #
858
+ def a?
859
+ CLASSFUL.key(8) === bits
860
+ end
861
+
862
+ #
863
+ # Checks whether the ip address belongs to a
864
+ # RFC 791 CLASS B network, no matter
865
+ # what the subnet mask is.
866
+ #
867
+ # Example:
868
+ #
869
+ # ip = IPAddress("172.16.10.1/24")
870
+ #
871
+ # ip.b?
872
+ # #=> true
873
+ #
874
+ def b?
875
+ CLASSFUL.key(16) === bits
876
+ end
877
+
878
+ #
879
+ # Checks whether the ip address belongs to a
880
+ # RFC 791 CLASS C network, no matter
881
+ # what the subnet mask is.
882
+ #
883
+ # Example:
884
+ #
885
+ # ip = IPAddress("192.168.1.1/30")
886
+ #
887
+ # ip.c?
888
+ # #=> true
889
+ #
890
+ def c?
891
+ CLASSFUL.key(24) === bits
892
+ end
893
+
894
+ #
895
+ # Return the ip address in a format compatible
896
+ # with the IPv6 Mapped IPv4 addresses
897
+ #
898
+ # Example:
899
+ #
900
+ # ip = IPAddress("172.16.10.1/24")
901
+ #
902
+ # ip.to_ipv6
903
+ # #=> "ac10:0a01"
904
+ #
905
+ def to_ipv6
906
+ "%.4x:%.4x" % [to_u32].pack("N").unpack("nn")
907
+ end
908
+
909
+ #
910
+ # Creates a new IPv4 object from an
911
+ # unsigned 32bits integer.
912
+ #
913
+ # ip = IPAddress::IPv4::parse_u32(167772160)
914
+ #
915
+ # ip.prefix = 8
916
+ # ip.to_string
917
+ # #=> "10.0.0.0/8"
918
+ #
919
+ # The +prefix+ parameter is optional:
920
+ #
921
+ # ip = IPAddress::IPv4::parse_u32(167772160, 8)
922
+ #
923
+ # ip.to_string
924
+ # #=> "10.0.0.0/8"
925
+ #
926
+ def self.parse_u32(u32, prefix=32)
927
+ self.new([u32].pack("N").unpack("C4").join(".")+"/#{prefix}")
928
+ end
929
+
930
+ #
931
+ # Creates a new IPv4 object from binary data,
932
+ # like the one you get from a network stream.
933
+ #
934
+ # For example, on a network stream the IP 172.16.0.1
935
+ # is represented with the binary "\254\020\n\001".
936
+ #
937
+ # ip = IPAddress::IPv4::parse_data "\254\020\n\001"
938
+ # ip.prefix = 24
939
+ #
940
+ # ip.to_string
941
+ # #=> "172.16.10.1/24"
942
+ #
943
+ def self.parse_data(str, prefix=32)
944
+ self.new(str.unpack("C4").join(".")+"/#{prefix}")
945
+ end
946
+
947
+ #
948
+ # Extract an IPv4 address from a string and
949
+ # returns a new object
950
+ #
951
+ # Example:
952
+ #
953
+ # str = "foobar172.16.10.1barbaz"
954
+ # ip = IPAddress::IPv4::extract str
955
+ #
956
+ # ip.to_s
957
+ # #=> "172.16.10.1"
958
+ #
959
+ def self.extract(str)
960
+ self.new REGEXP.match(str).to_s
961
+ end
962
+
963
+ #
964
+ # Summarization (or aggregation) is the process when two or more
965
+ # networks are taken together to check if a supernet, including all
966
+ # and only these networks, exists. If it exists then this supernet
967
+ # is called the summarized (or aggregated) network.
968
+ #
969
+ # It is very important to understand that summarization can only
970
+ # occur if there are no holes in the aggregated network, or, in other
971
+ # words, if the given networks fill completely the address space
972
+ # of the supernet. So the two rules are:
973
+ #
974
+ # 1) The aggregate network must contain +all+ the IP addresses of the
975
+ # original networks;
976
+ # 2) The aggregate network must contain +only+ the IP addresses of the
977
+ # original networks;
978
+ #
979
+ # A few examples will help clarify the above. Let's consider for
980
+ # instance the following two networks:
981
+ #
982
+ # ip1 = IPAddress("172.16.10.0/24")
983
+ # ip2 = IPAddress("172.16.11.0/24")
984
+ #
985
+ # These two networks can be expressed using only one IP address
986
+ # network if we change the prefix. Let Ruby do the work:
987
+ #
988
+ # IPAddress::IPv4::summarize(ip1,ip2).to_s
989
+ # #=> "172.16.10.0/23"
990
+ #
991
+ # We note how the network "172.16.10.0/23" includes all the addresses
992
+ # specified in the above networks, and (more important) includes
993
+ # ONLY those addresses.
994
+ #
995
+ # If we summarized +ip1+ and +ip2+ with the following network:
996
+ #
997
+ # "172.16.0.0/16"
998
+ #
999
+ # we would have satisfied rule #1 above, but not rule #2. So "172.16.0.0/16"
1000
+ # is not an aggregate network for +ip1+ and +ip2+.
1001
+ #
1002
+ # If it's not possible to compute a single aggregated network for all the
1003
+ # original networks, the method returns an array with all the aggregate
1004
+ # networks found. For example, the following four networks can be
1005
+ # aggregated in a single /22:
1006
+ #
1007
+ # ip1 = IPAddress("10.0.0.1/24")
1008
+ # ip2 = IPAddress("10.0.1.1/24")
1009
+ # ip3 = IPAddress("10.0.2.1/24")
1010
+ # ip4 = IPAddress("10.0.3.1/24")
1011
+ #
1012
+ # IPAddress::IPv4::summarize(ip1,ip2,ip3,ip4).to_string
1013
+ # #=> "10.0.0.0/22",
1014
+ #
1015
+ # But the following networks can't be summarized in a single network:
1016
+ #
1017
+ # ip1 = IPAddress("10.0.1.1/24")
1018
+ # ip2 = IPAddress("10.0.2.1/24")
1019
+ # ip3 = IPAddress("10.0.3.1/24")
1020
+ # ip4 = IPAddress("10.0.4.1/24")
1021
+ #
1022
+ # IPAddress::IPv4::summarize(ip1,ip2,ip3,ip4).map{|i| i.to_string}
1023
+ # #=> ["10.0.1.0/24","10.0.2.0/23","10.0.4.0/24"]
1024
+ #
1025
+ def self.summarize(*args)
1026
+ # one network? no need to summarize
1027
+ return [args.first.network] if args.size == 1
1028
+
1029
+ i = 0
1030
+ result = args.dup.sort.map{|ip| ip.network}
1031
+ while i < result.size-1
1032
+ sum = result[i] + result[i+1]
1033
+ result[i..i+1] = sum.first if sum.size == 1
1034
+ i += 1
1035
+ end
1036
+
1037
+ result.flatten!
1038
+ if result.size == args.size
1039
+ # nothing more to summarize
1040
+ return result
1041
+ else
1042
+ # keep on summarizing
1043
+ return self.summarize(*result)
1044
+ end
1045
+ end
1046
+
1047
+ #
1048
+ # Creates a new IPv4 address object by parsing the
1049
+ # address in a classful way.
1050
+ #
1051
+ # Classful addresses have a fixed netmask based on the
1052
+ # class they belong to:
1053
+ #
1054
+ # * Class A, from 0.0.0.0 to 127.255.255.255
1055
+ # * Class B, from 128.0.0.0 to 191.255.255.255
1056
+ # * Class C, D and E, from 192.0.0.0 to 255.255.255.254
1057
+ #
1058
+ # Example:
1059
+ #
1060
+ # ip = IPAddress::IPv4.parse_classful "10.0.0.1"
1061
+ #
1062
+ # ip.netmask
1063
+ # #=> "255.0.0.0"
1064
+ # ip.a?
1065
+ # #=> true
1066
+ #
1067
+ # Note that classes C, D and E will all have a default
1068
+ # prefix of /24 or 255.255.255.0
1069
+ #
1070
+ def self.parse_classful(ip)
1071
+ if IPAddress.valid_ipv4?(ip)
1072
+ address = ip.strip
1073
+ else
1074
+ raise ArgumentError, "Invalid IP #{ip.inspect}"
1075
+ end
1076
+ prefix = CLASSFUL.find{|h,k| h === ("%.8b" % address.to_i)}.last
1077
+ self.new "#{address}/#{prefix}"
1078
+ end
1079
+
1080
+ #
1081
+ # private methods
1082
+ #
1083
+ private
1084
+
1085
+ # Tweaked to remove the #upto(32)
1086
+ def newprefix(num)
1087
+ return @prefix + (Math::log2(num).ceil )
1088
+ end
1089
+
1090
+ def sum_first_found(arr)
1091
+ dup = arr.dup.reverse
1092
+ dup.each_with_index do |obj,i|
1093
+ a = [self.class.summarize(obj,dup[i+1])].flatten
1094
+ if a.size == 1
1095
+ dup[i..i+1] = a
1096
+ return dup.reverse
1097
+ end
1098
+ end
1099
+ return dup.reverse
1100
+ end
1101
+
1102
+ def aggregate(ip1,ip2)
1103
+ return [ip1] if ip1.include? ip2
1104
+
1105
+ snet = ip1.supernet(ip1.prefix-1)
1106
+ if snet.include_all?(ip1, ip2) && ((ip1.size + ip2.size) == snet.size)
1107
+ return [snet]
1108
+ else
1109
+ return [ip1, ip2]
1110
+ end
1111
+ end
1112
+ end # class IPv4
1113
+ end # module IPAddress
1114
+