From 7bdd3c222f4ac9f577342e127ddb90c3d4997077 Mon Sep 17 00:00:00 2001 From: liu_peng <16200780@qq.com> Date: Mon, 2 Feb 2015 12:31:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0.1/doc/apidocs/allclasses-frame.html | 24 + .../0.1/doc/apidocs/allclasses-noframe.html | 24 + .../doc/apidocs/be/jvb/ipv6/IPv6Address.html | 449 +++++++++++ .../be/jvb/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../apidocs/be/jvb/ipv6/IPv6AddressPool.html | 356 +++++++++ .../apidocs/be/jvb/ipv6/IPv6AddressRange.html | 466 ++++++++++++ .../doc/apidocs/be/jvb/ipv6/IPv6Network.html | 370 +++++++++ .../be/jvb/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../be/jvb/ipv6/class-use/IPv6Address.html | 253 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../jvb/ipv6/class-use/IPv6AddressPool.html | 154 ++++ .../jvb/ipv6/class-use/IPv6AddressRange.html | 205 +++++ .../be/jvb/ipv6/class-use/IPv6Network.html | 173 +++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../apidocs/be/jvb/ipv6/package-frame.html | 25 + .../apidocs/be/jvb/ipv6/package-summary.html | 165 ++++ .../doc/apidocs/be/jvb/ipv6/package-tree.html | 132 ++++ .../doc/apidocs/be/jvb/ipv6/package-use.html | 150 ++++ .../0.1/doc/apidocs/constant-values.html | 115 +++ .../0.1/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.1/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.1/doc/apidocs/index-all.html | 344 +++++++++ artifacts/0.1/doc/apidocs/index.html | 31 + artifacts/0.1/doc/apidocs/overview-tree.html | 136 ++++ artifacts/0.1/doc/apidocs/package-list | 1 + .../0.1/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.1/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.1/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.1/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.10/doc/apidocs/allclasses-frame.html | 25 + .../0.10/doc/apidocs/allclasses-noframe.html | 25 + .../com/googlecode/ipv6/IPv6Address.html | 515 +++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 474 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 467 ++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 368 +++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 328 ++++++++ .../ipv6/class-use/IPv6Address.html | 263 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../ipv6/class-use/IPv6AddressPool.html | 161 ++++ .../ipv6/class-use/IPv6AddressRange.html | 222 ++++++ .../ipv6/class-use/IPv6Network.html | 204 +++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../ipv6/class-use/IPv6NetworkMask.html | 187 +++++ .../com/googlecode/ipv6/package-frame.html | 26 + .../com/googlecode/ipv6/package-summary.html | 171 +++++ .../com/googlecode/ipv6/package-tree.html | 133 ++++ .../com/googlecode/ipv6/package-use.html | 155 ++++ .../0.10/doc/apidocs/constant-values.html | 115 +++ .../0.10/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.10/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.10/doc/apidocs/index-all.html | 405 ++++++++++ artifacts/0.10/doc/apidocs/index.html | 31 + artifacts/0.10/doc/apidocs/overview-tree.html | 137 ++++ artifacts/0.10/doc/apidocs/package-list | 1 + .../0.10/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.10/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.10/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.10/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.11/doc/apidocs/allclasses-frame.html | 25 + .../0.11/doc/apidocs/allclasses-noframe.html | 25 + .../com/googlecode/ipv6/IPv6Address.html | 554 ++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 474 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 467 ++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 368 +++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 328 ++++++++ .../ipv6/class-use/IPv6Address.html | 276 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../ipv6/class-use/IPv6AddressPool.html | 161 ++++ .../ipv6/class-use/IPv6AddressRange.html | 222 ++++++ .../ipv6/class-use/IPv6Network.html | 204 +++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../ipv6/class-use/IPv6NetworkMask.html | 187 +++++ .../com/googlecode/ipv6/package-frame.html | 26 + .../com/googlecode/ipv6/package-summary.html | 171 +++++ .../com/googlecode/ipv6/package-tree.html | 133 ++++ .../com/googlecode/ipv6/package-use.html | 155 ++++ .../0.11/doc/apidocs/constant-values.html | 115 +++ .../0.11/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.11/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.11/doc/apidocs/index-all.html | 413 ++++++++++ artifacts/0.11/doc/apidocs/index.html | 31 + artifacts/0.11/doc/apidocs/overview-tree.html | 137 ++++ artifacts/0.11/doc/apidocs/package-list | 1 + .../0.11/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.11/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.11/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.11/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.12/doc/apidocs/allclasses-frame.html | 25 + .../0.12/doc/apidocs/allclasses-noframe.html | 25 + .../com/googlecode/ipv6/IPv6Address.html | 618 +++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 474 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 467 ++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 368 +++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 328 ++++++++ .../ipv6/class-use/IPv6Address.html | 276 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../ipv6/class-use/IPv6AddressPool.html | 161 ++++ .../ipv6/class-use/IPv6AddressRange.html | 222 ++++++ .../ipv6/class-use/IPv6Network.html | 204 +++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../ipv6/class-use/IPv6NetworkMask.html | 187 +++++ .../com/googlecode/ipv6/package-frame.html | 26 + .../com/googlecode/ipv6/package-summary.html | 171 +++++ .../com/googlecode/ipv6/package-tree.html | 133 ++++ .../com/googlecode/ipv6/package-use.html | 155 ++++ .../0.12/doc/apidocs/constant-values.html | 115 +++ .../0.12/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.12/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.12/doc/apidocs/index-all.html | 425 +++++++++++ artifacts/0.12/doc/apidocs/index.html | 31 + artifacts/0.12/doc/apidocs/overview-tree.html | 137 ++++ artifacts/0.12/doc/apidocs/package-list | 1 + .../0.12/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.12/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.12/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.12/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.13/doc/apidocs/allclasses-frame.html | 25 + .../0.13/doc/apidocs/allclasses-noframe.html | 25 + .../com/googlecode/ipv6/IPv6Address.html | 618 +++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 474 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 467 ++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 430 +++++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 328 ++++++++ .../ipv6/class-use/IPv6Address.html | 276 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../ipv6/class-use/IPv6AddressPool.html | 161 ++++ .../ipv6/class-use/IPv6AddressRange.html | 222 ++++++ .../ipv6/class-use/IPv6Network.html | 225 ++++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../ipv6/class-use/IPv6NetworkMask.html | 187 +++++ .../com/googlecode/ipv6/package-frame.html | 26 + .../com/googlecode/ipv6/package-summary.html | 171 +++++ .../com/googlecode/ipv6/package-tree.html | 133 ++++ .../com/googlecode/ipv6/package-use.html | 155 ++++ .../0.13/doc/apidocs/constant-values.html | 115 +++ .../0.13/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.13/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.13/doc/apidocs/index-all.html | 437 +++++++++++ artifacts/0.13/doc/apidocs/index.html | 31 + artifacts/0.13/doc/apidocs/overview-tree.html | 137 ++++ artifacts/0.13/doc/apidocs/package-list | 1 + .../0.13/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.13/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.13/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.13/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.14/doc/apidocs/allclasses-frame.html | 25 + .../0.14/doc/apidocs/allclasses-noframe.html | 25 + .../com/googlecode/ipv6/IPv6Address.html | 707 ++++++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 474 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 480 ++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 450 +++++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 328 ++++++++ .../ipv6/class-use/IPv6Address.html | 301 ++++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../ipv6/class-use/IPv6AddressPool.html | 161 ++++ .../ipv6/class-use/IPv6AddressRange.html | 222 ++++++ .../ipv6/class-use/IPv6Network.html | 231 ++++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../ipv6/class-use/IPv6NetworkMask.html | 193 +++++ .../com/googlecode/ipv6/package-frame.html | 26 + .../com/googlecode/ipv6/package-summary.html | 171 +++++ .../com/googlecode/ipv6/package-tree.html | 133 ++++ .../com/googlecode/ipv6/package-use.html | 155 ++++ .../0.14/doc/apidocs/constant-values.html | 115 +++ .../0.14/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.14/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.14/doc/apidocs/index-all.html | 455 +++++++++++ artifacts/0.14/doc/apidocs/index.html | 31 + artifacts/0.14/doc/apidocs/overview-tree.html | 137 ++++ artifacts/0.14/doc/apidocs/package-list | 1 + .../0.14/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.14/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.14/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.14/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.15/doc/apidocs/allclasses-frame.html | 25 + .../0.15/doc/apidocs/allclasses-noframe.html | 25 + .../com/googlecode/ipv6/IPv6Address.html | 707 ++++++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 474 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 500 +++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 450 +++++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 328 ++++++++ .../ipv6/class-use/IPv6Address.html | 301 ++++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../ipv6/class-use/IPv6AddressPool.html | 161 ++++ .../ipv6/class-use/IPv6AddressRange.html | 222 ++++++ .../ipv6/class-use/IPv6Network.html | 238 ++++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../ipv6/class-use/IPv6NetworkMask.html | 193 +++++ .../com/googlecode/ipv6/package-frame.html | 26 + .../com/googlecode/ipv6/package-summary.html | 171 +++++ .../com/googlecode/ipv6/package-tree.html | 133 ++++ .../com/googlecode/ipv6/package-use.html | 155 ++++ .../0.15/doc/apidocs/constant-values.html | 115 +++ .../0.15/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.15/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.15/doc/apidocs/index-all.html | 460 ++++++++++++ artifacts/0.15/doc/apidocs/index.html | 31 + artifacts/0.15/doc/apidocs/overview-tree.html | 137 ++++ artifacts/0.15/doc/apidocs/package-list | 1 + .../0.15/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.15/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.15/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.15/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.2/doc/apidocs/allclasses-frame.html | 24 + .../0.2/doc/apidocs/allclasses-noframe.html | 24 + .../doc/apidocs/be/jvb/ipv6/IPv6Address.html | 449 +++++++++++ .../be/jvb/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../apidocs/be/jvb/ipv6/IPv6AddressPool.html | 405 ++++++++++ .../apidocs/be/jvb/ipv6/IPv6AddressRange.html | 466 ++++++++++++ .../doc/apidocs/be/jvb/ipv6/IPv6Network.html | 370 +++++++++ .../be/jvb/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../be/jvb/ipv6/class-use/IPv6Address.html | 265 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../jvb/ipv6/class-use/IPv6AddressPool.html | 154 ++++ .../jvb/ipv6/class-use/IPv6AddressRange.html | 207 +++++ .../be/jvb/ipv6/class-use/IPv6Network.html | 173 +++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../apidocs/be/jvb/ipv6/package-frame.html | 25 + .../apidocs/be/jvb/ipv6/package-summary.html | 165 ++++ .../doc/apidocs/be/jvb/ipv6/package-tree.html | 132 ++++ .../doc/apidocs/be/jvb/ipv6/package-use.html | 150 ++++ .../0.2/doc/apidocs/constant-values.html | 115 +++ .../0.2/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.2/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.2/doc/apidocs/index-all.html | 354 +++++++++ artifacts/0.2/doc/apidocs/index.html | 31 + artifacts/0.2/doc/apidocs/overview-tree.html | 136 ++++ artifacts/0.2/doc/apidocs/package-list | 1 + .../0.2/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.2/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.2/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.2/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.3/doc/apidocs/allclasses-frame.html | 24 + .../0.3/doc/apidocs/allclasses-noframe.html | 24 + .../doc/apidocs/be/jvb/ipv6/IPv6Address.html | 449 +++++++++++ .../be/jvb/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../apidocs/be/jvb/ipv6/IPv6AddressPool.html | 484 ++++++++++++ .../apidocs/be/jvb/ipv6/IPv6AddressRange.html | 466 ++++++++++++ .../doc/apidocs/be/jvb/ipv6/IPv6Network.html | 370 +++++++++ .../be/jvb/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../be/jvb/ipv6/class-use/IPv6Address.html | 265 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../jvb/ipv6/class-use/IPv6AddressPool.html | 154 ++++ .../jvb/ipv6/class-use/IPv6AddressRange.html | 207 +++++ .../be/jvb/ipv6/class-use/IPv6Network.html | 190 +++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../apidocs/be/jvb/ipv6/package-frame.html | 25 + .../apidocs/be/jvb/ipv6/package-summary.html | 165 ++++ .../doc/apidocs/be/jvb/ipv6/package-tree.html | 132 ++++ .../doc/apidocs/be/jvb/ipv6/package-use.html | 150 ++++ .../0.3/doc/apidocs/constant-values.html | 115 +++ .../0.3/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.3/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.3/doc/apidocs/index-all.html | 364 +++++++++ artifacts/0.3/doc/apidocs/index.html | 31 + artifacts/0.3/doc/apidocs/overview-tree.html | 136 ++++ artifacts/0.3/doc/apidocs/package-list | 1 + .../0.3/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.3/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.3/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.3/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.4/doc/apidocs/allclasses-frame.html | 25 + .../0.4/doc/apidocs/allclasses-noframe.html | 25 + .../doc/apidocs/be/jvb/ipv6/IPv6Address.html | 537 +++++++++++++ .../be/jvb/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../apidocs/be/jvb/ipv6/IPv6AddressPool.html | 484 ++++++++++++ .../apidocs/be/jvb/ipv6/IPv6AddressRange.html | 466 ++++++++++++ .../doc/apidocs/be/jvb/ipv6/IPv6Network.html | 401 ++++++++++ .../be/jvb/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../apidocs/be/jvb/ipv6/IPv6NetworkMask.html | 348 +++++++++ .../be/jvb/ipv6/class-use/IPv6Address.html | 280 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../jvb/ipv6/class-use/IPv6AddressPool.html | 154 ++++ .../jvb/ipv6/class-use/IPv6AddressRange.html | 207 +++++ .../be/jvb/ipv6/class-use/IPv6Network.html | 190 +++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../jvb/ipv6/class-use/IPv6NetworkMask.html | 175 +++++ .../apidocs/be/jvb/ipv6/package-frame.html | 26 + .../apidocs/be/jvb/ipv6/package-summary.html | 171 +++++ .../doc/apidocs/be/jvb/ipv6/package-tree.html | 133 ++++ .../doc/apidocs/be/jvb/ipv6/package-use.html | 155 ++++ .../0.4/doc/apidocs/constant-values.html | 115 +++ .../0.4/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.4/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.4/doc/apidocs/index-all.html | 408 ++++++++++ artifacts/0.4/doc/apidocs/index.html | 31 + artifacts/0.4/doc/apidocs/overview-tree.html | 137 ++++ artifacts/0.4/doc/apidocs/package-list | 1 + .../0.4/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.4/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.4/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.4/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.5/doc/apidocs/allclasses-frame.html | 25 + .../0.5/doc/apidocs/allclasses-noframe.html | 25 + .../com/googlecode/ipv6/IPv6Address.html | 551 ++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 498 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 480 ++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 405 ++++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 348 +++++++++ .../ipv6/class-use/IPv6Address.html | 280 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../ipv6/class-use/IPv6AddressPool.html | 154 ++++ .../ipv6/class-use/IPv6AddressRange.html | 207 +++++ .../ipv6/class-use/IPv6Network.html | 190 +++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../ipv6/class-use/IPv6NetworkMask.html | 182 +++++ .../com/googlecode/ipv6/package-frame.html | 26 + .../com/googlecode/ipv6/package-summary.html | 171 +++++ .../com/googlecode/ipv6/package-tree.html | 133 ++++ .../com/googlecode/ipv6/package-use.html | 155 ++++ .../0.5/doc/apidocs/constant-values.html | 115 +++ .../0.5/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.5/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.5/doc/apidocs/index-all.html | 408 ++++++++++ artifacts/0.5/doc/apidocs/index.html | 31 + artifacts/0.5/doc/apidocs/overview-tree.html | 137 ++++ artifacts/0.5/doc/apidocs/package-list | 1 + .../0.5/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.5/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.5/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.5/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.6/doc/apidocs/allclasses-frame.html | 25 + .../0.6/doc/apidocs/allclasses-noframe.html | 25 + .../com/googlecode/ipv6/IPv6Address.html | 515 +++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 474 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 459 ++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 368 +++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 328 ++++++++ .../ipv6/class-use/IPv6Address.html | 263 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../ipv6/class-use/IPv6AddressPool.html | 161 ++++ .../ipv6/class-use/IPv6AddressRange.html | 219 ++++++ .../ipv6/class-use/IPv6Network.html | 204 +++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../ipv6/class-use/IPv6NetworkMask.html | 187 +++++ .../com/googlecode/ipv6/package-frame.html | 26 + .../com/googlecode/ipv6/package-summary.html | 171 +++++ .../com/googlecode/ipv6/package-tree.html | 133 ++++ .../com/googlecode/ipv6/package-use.html | 155 ++++ .../0.6/doc/apidocs/constant-values.html | 115 +++ .../0.6/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.6/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.6/doc/apidocs/index-all.html | 402 ++++++++++ artifacts/0.6/doc/apidocs/index.html | 31 + artifacts/0.6/doc/apidocs/overview-tree.html | 137 ++++ artifacts/0.6/doc/apidocs/package-list | 1 + .../0.6/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.6/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.6/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.6/doc/apidocs/stylesheet.css | 474 ++++++++++++ .../0.7/doc/apidocs/allclasses-frame.html | 46 ++ .../0.7/doc/apidocs/allclasses-noframe.html | 46 ++ .../com/googlecode/ipv6/BitSetHelpers.html | 232 ++++++ .../com/googlecode/ipv6/IPv6Address.html | 652 ++++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 280 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 561 ++++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 561 ++++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 399 ++++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 358 +++++++++ .../ipv6/class-use/BitSetHelpers.html | 143 ++++ .../ipv6/class-use/IPv6Address.html | 345 +++++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 143 ++++ .../ipv6/class-use/IPv6AddressPool.html | 191 +++++ .../ipv6/class-use/IPv6AddressRange.html | 272 +++++++ .../ipv6/class-use/IPv6Network.html | 248 ++++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 143 ++++ .../ipv6/class-use/IPv6NetworkMask.html | 224 ++++++ .../com/googlecode/ipv6/package-frame.html | 47 ++ .../com/googlecode/ipv6/package-summary.html | 184 +++++ .../com/googlecode/ipv6/package-tree.html | 153 ++++ .../com/googlecode/ipv6/package-use.html | 180 +++++ .../0.7/doc/apidocs/constant-values.html | 145 ++++ .../0.7/doc/apidocs/deprecated-list.html | 145 ++++ artifacts/0.7/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.7/doc/apidocs/index-all.html | 424 +++++++++++ artifacts/0.7/doc/apidocs/index.html | 37 + artifacts/0.7/doc/apidocs/overview-tree.html | 155 ++++ artifacts/0.7/doc/apidocs/package-list | 1 + .../0.7/doc/apidocs/resources/inherit.gif | Bin 0 -> 57 bytes artifacts/0.7/doc/apidocs/stylesheet.css | 29 + .../0.8/doc/apidocs/allclasses-frame.html | 44 ++ .../0.8/doc/apidocs/allclasses-noframe.html | 44 ++ .../com/googlecode/ipv6/IPv6Address.html | 652 ++++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 280 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 561 ++++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 568 ++++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 399 ++++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 358 +++++++++ .../ipv6/class-use/IPv6Address.html | 345 +++++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 143 ++++ .../ipv6/class-use/IPv6AddressPool.html | 191 +++++ .../ipv6/class-use/IPv6AddressRange.html | 273 +++++++ .../ipv6/class-use/IPv6Network.html | 248 ++++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 143 ++++ .../ipv6/class-use/IPv6NetworkMask.html | 224 ++++++ .../com/googlecode/ipv6/package-frame.html | 45 ++ .../com/googlecode/ipv6/package-summary.html | 180 +++++ .../com/googlecode/ipv6/package-tree.html | 153 ++++ .../com/googlecode/ipv6/package-use.html | 180 +++++ .../0.8/doc/apidocs/constant-values.html | 145 ++++ .../0.8/doc/apidocs/deprecated-list.html | 145 ++++ artifacts/0.8/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.8/doc/apidocs/index-all.html | 417 +++++++++++ artifacts/0.8/doc/apidocs/index.html | 37 + artifacts/0.8/doc/apidocs/overview-tree.html | 155 ++++ artifacts/0.8/doc/apidocs/package-list | 1 + .../0.8/doc/apidocs/resources/inherit.gif | Bin 0 -> 57 bytes artifacts/0.8/doc/apidocs/stylesheet.css | 29 + .../0.9/doc/apidocs/allclasses-frame.html | 25 + .../0.9/doc/apidocs/allclasses-noframe.html | 25 + .../com/googlecode/ipv6/IPv6Address.html | 515 +++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 474 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 467 ++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 368 +++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 328 ++++++++ .../ipv6/class-use/IPv6Address.html | 263 +++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../ipv6/class-use/IPv6AddressPool.html | 161 ++++ .../ipv6/class-use/IPv6AddressRange.html | 222 ++++++ .../ipv6/class-use/IPv6Network.html | 204 +++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../ipv6/class-use/IPv6NetworkMask.html | 187 +++++ .../com/googlecode/ipv6/package-frame.html | 26 + .../com/googlecode/ipv6/package-summary.html | 171 +++++ .../com/googlecode/ipv6/package-tree.html | 133 ++++ .../com/googlecode/ipv6/package-use.html | 155 ++++ .../0.9/doc/apidocs/constant-values.html | 115 +++ .../0.9/doc/apidocs/deprecated-list.html | 115 +++ artifacts/0.9/doc/apidocs/help-doc.html | 216 ++++++ artifacts/0.9/doc/apidocs/index-all.html | 405 ++++++++++ artifacts/0.9/doc/apidocs/index.html | 31 + artifacts/0.9/doc/apidocs/overview-tree.html | 137 ++++ artifacts/0.9/doc/apidocs/package-list | 1 + .../0.9/doc/apidocs/resources/background.gif | Bin 0 -> 2313 bytes artifacts/0.9/doc/apidocs/resources/tab.gif | Bin 0 -> 291 bytes .../0.9/doc/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../doc/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes artifacts/0.9/doc/apidocs/stylesheet.css | 474 ++++++++++++ release.txt | 12 + tags/ipv6-0.1/pom.xml | 41 + .../main/java/be/jvb/ipv6/IPv6Address.java | 299 ++++++++ .../java/be/jvb/ipv6/IPv6AddressHelpers.java | 110 +++ .../java/be/jvb/ipv6/IPv6AddressPool.java | 303 ++++++++ .../java/be/jvb/ipv6/IPv6AddressRange.java | 194 +++++ .../main/java/be/jvb/ipv6/IPv6Network.java | 114 +++ .../java/be/jvb/ipv6/IPv6NetworkHelpers.java | 30 + .../src/test/java/be/jvb/ipv6/Examples.java | 53 ++ .../java/be/jvb/ipv6/IPv6AddressPoolTest.java | 171 +++++ .../be/jvb/ipv6/IPv6AddressRangeTest.java | 90 +++ .../java/be/jvb/ipv6/IPv6AddressTest.java | 221 ++++++ .../be/jvb/ipv6/IPv6NetworkHelpersTest.java | 25 + .../java/be/jvb/ipv6/IPv6NetworkTest.java | 42 ++ tags/ipv6-0.2/pom.xml | 48 ++ .../main/java/be/jvb/ipv6/IPv6Address.java | 305 ++++++++ .../java/be/jvb/ipv6/IPv6AddressHelpers.java | 110 +++ .../java/be/jvb/ipv6/IPv6AddressPool.java | 332 ++++++++ .../java/be/jvb/ipv6/IPv6AddressRange.java | 194 +++++ .../main/java/be/jvb/ipv6/IPv6Network.java | 116 +++ .../java/be/jvb/ipv6/IPv6NetworkHelpers.java | 30 + .../src/test/java/be/jvb/ipv6/Examples.java | 53 ++ .../java/be/jvb/ipv6/IPv6AddressPoolTest.java | 171 +++++ .../be/jvb/ipv6/IPv6AddressRangeTest.java | 90 +++ .../java/be/jvb/ipv6/IPv6AddressTest.java | 221 ++++++ .../be/jvb/ipv6/IPv6NetworkHelpersTest.java | 25 + .../java/be/jvb/ipv6/IPv6NetworkTest.java | 42 ++ tags/ipv6-0.3/pom.xml | 48 ++ .../main/java/be/jvb/ipv6/IPv6Address.java | 341 +++++++++ .../java/be/jvb/ipv6/IPv6AddressHelpers.java | 110 +++ .../java/be/jvb/ipv6/IPv6AddressPool.java | 459 ++++++++++++ .../java/be/jvb/ipv6/IPv6AddressRange.java | 198 +++++ .../main/java/be/jvb/ipv6/IPv6Network.java | 116 +++ .../java/be/jvb/ipv6/IPv6NetworkHelpers.java | 30 + .../src/test/java/be/jvb/ipv6/Examples.java | 53 ++ .../java/be/jvb/ipv6/IPv6AddressPoolTest.java | 224 ++++++ .../be/jvb/ipv6/IPv6AddressRangeTest.java | 90 +++ .../java/be/jvb/ipv6/IPv6AddressTest.java | 220 ++++++ .../be/jvb/ipv6/IPv6NetworkHelpersTest.java | 25 + .../java/be/jvb/ipv6/IPv6NetworkTest.java | 42 ++ tags/ipv6-0.4/pom.xml | 48 ++ .../main/java/be/jvb/ipv6/IPv6Address.java | 349 +++++++++ .../java/be/jvb/ipv6/IPv6AddressHelpers.java | 110 +++ .../java/be/jvb/ipv6/IPv6AddressPool.java | 453 +++++++++++ .../java/be/jvb/ipv6/IPv6AddressRange.java | 194 +++++ .../main/java/be/jvb/ipv6/IPv6Network.java | 140 ++++ .../java/be/jvb/ipv6/IPv6NetworkHelpers.java | 30 + .../java/be/jvb/ipv6/IPv6NetworkMask.java | 120 +++ .../java/be/jvb/ipv6/IPv6AddressPoolTest.java | 223 ++++++ .../be/jvb/ipv6/IPv6AddressRangeTest.java | 90 +++ .../java/be/jvb/ipv6/IPv6AddressTest.java | 251 +++++++ .../be/jvb/ipv6/IPv6NetworkHelpersTest.java | 25 + .../java/be/jvb/ipv6/IPv6NetworkMaskTest.java | 42 ++ .../java/be/jvb/ipv6/IPv6NetworkTest.java | 68 ++ .../java/be/jvb/ipv6/examples/Examples.java | 93 +++ tags/java-ipv6-0.10/LICENSE | 202 +++++ tags/java-ipv6-0.10/NOTICE | 2 + tags/java-ipv6-0.10/pom.xml | 143 ++++ .../com/googlecode/ipv6/BitSetHelpers.java | 51 ++ .../java/com/googlecode/ipv6/IPv6Address.java | 402 ++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 126 ++++ .../com/googlecode/ipv6/IPv6AddressPool.java | 483 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 232 ++++++ .../java/com/googlecode/ipv6/IPv6Network.java | 149 ++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 48 ++ .../com/googlecode/ipv6/IPv6NetworkMask.java | 150 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 274 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 135 ++++ .../com/googlecode/ipv6/IPv6AddressTest.java | 278 +++++++ .../ipv6/IPv6NetworkHelpersTest.java | 41 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 58 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 112 +++ .../googlecode/ipv6/examples/Examples.java | 113 +++ tags/java-ipv6-0.11/LICENSE | 202 +++++ tags/java-ipv6-0.11/NOTICE | 2 + tags/java-ipv6-0.11/pom.xml | 143 ++++ .../com/googlecode/ipv6/BitSetHelpers.java | 51 ++ .../java/com/googlecode/ipv6/IPv6Address.java | 470 ++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 126 ++++ .../com/googlecode/ipv6/IPv6AddressPool.java | 483 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 232 ++++++ .../java/com/googlecode/ipv6/IPv6Network.java | 149 ++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 48 ++ .../com/googlecode/ipv6/IPv6NetworkMask.java | 150 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 274 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 135 ++++ .../com/googlecode/ipv6/IPv6AddressTest.java | 325 ++++++++ .../ipv6/IPv6NetworkHelpersTest.java | 41 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 58 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 112 +++ .../googlecode/ipv6/examples/Examples.java | 113 +++ tags/java-ipv6-0.12/LICENSE | 202 +++++ tags/java-ipv6-0.12/NOTICE | 2 + tags/java-ipv6-0.12/pom.xml | 143 ++++ .../com/googlecode/ipv6/BitSetHelpers.java | 51 ++ .../java/com/googlecode/ipv6/IPv6Address.java | 534 +++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 168 +++++ .../com/googlecode/ipv6/IPv6AddressPool.java | 483 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 232 ++++++ .../java/com/googlecode/ipv6/IPv6Network.java | 149 ++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 48 ++ .../com/googlecode/ipv6/IPv6NetworkMask.java | 150 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 274 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 135 ++++ .../com/googlecode/ipv6/IPv6AddressTest.java | 390 ++++++++++ .../ipv6/IPv6NetworkHelpersTest.java | 41 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 58 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 112 +++ .../googlecode/ipv6/examples/Examples.java | 114 +++ tags/java-ipv6-0.13/LICENSE | 202 +++++ tags/java-ipv6-0.13/NOTICE | 2 + tags/java-ipv6-0.13/pom.xml | 143 ++++ .../com/googlecode/ipv6/BitSetHelpers.java | 51 ++ .../java/com/googlecode/ipv6/IPv6Address.java | 534 +++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 168 +++++ .../com/googlecode/ipv6/IPv6AddressPool.java | 483 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 238 ++++++ .../java/com/googlecode/ipv6/IPv6Network.java | 156 ++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 48 ++ .../com/googlecode/ipv6/IPv6NetworkMask.java | 150 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 274 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 135 ++++ .../com/googlecode/ipv6/IPv6AddressTest.java | 390 ++++++++++ .../ipv6/IPv6NetworkHelpersTest.java | 41 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 58 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 126 ++++ .../googlecode/ipv6/examples/Examples.java | 114 +++ tags/java-ipv6-0.14/LICENSE | 202 +++++ tags/java-ipv6-0.14/NOTICE | 2 + tags/java-ipv6-0.14/pom.xml | 143 ++++ .../com/googlecode/ipv6/BitSetHelpers.java | 51 ++ .../java/com/googlecode/ipv6/IPv6Address.java | 602 +++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 175 +++++ .../com/googlecode/ipv6/IPv6AddressPool.java | 483 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 248 ++++++ .../java/com/googlecode/ipv6/IPv6Network.java | 225 ++++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 48 ++ .../com/googlecode/ipv6/IPv6NetworkMask.java | 150 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 274 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 148 ++++ .../com/googlecode/ipv6/IPv6AddressTest.java | 427 +++++++++++ .../ipv6/IPv6NetworkHelpersTest.java | 41 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 58 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 190 +++++ .../googlecode/ipv6/examples/Examples.java | 139 ++++ tags/java-ipv6-0.15/LICENSE | 202 +++++ tags/java-ipv6-0.15/NOTICE | 2 + tags/java-ipv6-0.15/pom.xml | 149 ++++ .../com/googlecode/ipv6/BitSetHelpers.java | 51 ++ .../java/com/googlecode/ipv6/IPv6Address.java | 602 +++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 175 +++++ .../com/googlecode/ipv6/IPv6AddressPool.java | 483 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 316 ++++++++ .../java/com/googlecode/ipv6/IPv6Network.java | 225 ++++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 48 ++ .../com/googlecode/ipv6/IPv6NetworkMask.java | 150 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 274 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 264 +++++++ .../com/googlecode/ipv6/IPv6AddressTest.java | 427 +++++++++++ .../ipv6/IPv6NetworkHelpersTest.java | 41 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 58 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 190 +++++ .../googlecode/ipv6/examples/Examples.java | 152 ++++ tags/java-ipv6-0.5/pom.xml | 115 +++ .../java/com/googlecode/ipv6/IPv6Address.java | 376 ++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 110 +++ .../com/googlecode/ipv6/IPv6AddressPool.java | 467 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 202 +++++ .../java/com/googlecode/ipv6/IPv6Network.java | 141 ++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 30 + .../com/googlecode/ipv6/IPv6NetworkMask.java | 120 +++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 227 ++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 92 +++ .../com/googlecode/ipv6/IPv6AddressTest.java | 264 +++++++ .../ipv6/IPv6NetworkHelpersTest.java | 26 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 44 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 71 ++ .../googlecode/ipv6/examples/Examples.java | 93 +++ tags/java-ipv6-0.6/pom.xml | 115 +++ .../java/com/googlecode/ipv6/IPv6Address.java | 382 ++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 110 +++ .../com/googlecode/ipv6/IPv6AddressPool.java | 467 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 207 +++++ .../java/com/googlecode/ipv6/IPv6Network.java | 133 ++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 30 + .../com/googlecode/ipv6/IPv6NetworkMask.java | 132 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 258 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 94 +++ .../com/googlecode/ipv6/IPv6AddressTest.java | 264 +++++++ .../ipv6/IPv6NetworkHelpersTest.java | 26 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 42 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 79 ++ .../googlecode/ipv6/examples/Examples.java | 97 +++ tags/java-ipv6-0.7/pom.xml | 115 +++ .../com/googlecode/ipv6/BitSetHelpers.java | 35 + .../java/com/googlecode/ipv6/IPv6Address.java | 382 ++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 110 +++ .../com/googlecode/ipv6/IPv6AddressPool.java | 467 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 207 +++++ .../java/com/googlecode/ipv6/IPv6Network.java | 133 ++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 32 + .../com/googlecode/ipv6/IPv6NetworkMask.java | 134 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 258 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 94 +++ .../com/googlecode/ipv6/IPv6AddressTest.java | 264 +++++++ .../ipv6/IPv6NetworkHelpersTest.java | 26 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 42 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 79 ++ .../googlecode/ipv6/examples/Examples.java | 97 +++ tags/java-ipv6-0.8/pom.xml | 115 +++ .../com/googlecode/ipv6/BitSetHelpers.java | 35 + .../java/com/googlecode/ipv6/IPv6Address.java | 382 ++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 110 +++ .../com/googlecode/ipv6/IPv6AddressPool.java | 467 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 216 ++++++ .../java/com/googlecode/ipv6/IPv6Network.java | 133 ++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 32 + .../com/googlecode/ipv6/IPv6NetworkMask.java | 134 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 258 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 119 +++ .../com/googlecode/ipv6/IPv6AddressTest.java | 264 +++++++ .../ipv6/IPv6NetworkHelpersTest.java | 26 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 42 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 79 ++ .../googlecode/ipv6/examples/Examples.java | 97 +++ tags/java-ipv6-0.9/pom.xml | 115 +++ .../com/googlecode/ipv6/BitSetHelpers.java | 35 + .../java/com/googlecode/ipv6/IPv6Address.java | 386 ++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 110 +++ .../com/googlecode/ipv6/IPv6AddressPool.java | 467 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 216 ++++++ .../java/com/googlecode/ipv6/IPv6Network.java | 133 ++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 32 + .../com/googlecode/ipv6/IPv6NetworkMask.java | 134 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 258 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 119 +++ .../com/googlecode/ipv6/IPv6AddressTest.java | 264 +++++++ .../ipv6/IPv6NetworkHelpersTest.java | 26 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 42 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 96 +++ .../googlecode/ipv6/examples/Examples.java | 97 +++ trunk/LICENSE | 202 +++++ trunk/NOTICE | 2 + trunk/pom.xml | 149 ++++ .../com/googlecode/ipv6/BitSetHelpers.java | 51 ++ .../java/com/googlecode/ipv6/IPv6Address.java | 602 +++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.java | 175 +++++ .../com/googlecode/ipv6/IPv6AddressPool.java | 483 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.java | 316 ++++++++ .../java/com/googlecode/ipv6/IPv6Network.java | 225 ++++++ .../googlecode/ipv6/IPv6NetworkHelpers.java | 48 ++ .../com/googlecode/ipv6/IPv6NetworkMask.java | 150 ++++ .../googlecode/ipv6/IPv6AddressPoolTest.java | 274 +++++++ .../googlecode/ipv6/IPv6AddressRangeTest.java | 264 +++++++ .../com/googlecode/ipv6/IPv6AddressTest.java | 427 +++++++++++ .../ipv6/IPv6NetworkHelpersTest.java | 41 + .../googlecode/ipv6/IPv6NetworkMaskTest.java | 58 ++ .../com/googlecode/ipv6/IPv6NetworkTest.java | 190 +++++ .../googlecode/ipv6/examples/Examples.java | 152 ++++ trunk/target/apidocs/allclasses-frame.html | 25 + trunk/target/apidocs/allclasses-noframe.html | 25 + .../com/googlecode/ipv6/IPv6Address.html | 707 ++++++++++++++++++ .../googlecode/ipv6/IPv6AddressHelpers.html | 274 +++++++ .../com/googlecode/ipv6/IPv6AddressPool.html | 474 ++++++++++++ .../com/googlecode/ipv6/IPv6AddressRange.html | 500 +++++++++++++ .../com/googlecode/ipv6/IPv6Network.html | 450 +++++++++++ .../googlecode/ipv6/IPv6NetworkHelpers.html | 231 ++++++ .../com/googlecode/ipv6/IPv6NetworkMask.html | 328 ++++++++ .../ipv6/class-use/IPv6Address.html | 301 ++++++++ .../ipv6/class-use/IPv6AddressHelpers.html | 115 +++ .../ipv6/class-use/IPv6AddressPool.html | 161 ++++ .../ipv6/class-use/IPv6AddressRange.html | 222 ++++++ .../ipv6/class-use/IPv6Network.html | 238 ++++++ .../ipv6/class-use/IPv6NetworkHelpers.html | 115 +++ .../ipv6/class-use/IPv6NetworkMask.html | 193 +++++ .../com/googlecode/ipv6/package-frame.html | 26 + .../com/googlecode/ipv6/package-summary.html | 171 +++++ .../com/googlecode/ipv6/package-tree.html | 133 ++++ .../com/googlecode/ipv6/package-use.html | 155 ++++ trunk/target/apidocs/constant-values.html | 115 +++ trunk/target/apidocs/deprecated-list.html | 115 +++ trunk/target/apidocs/help-doc.html | 216 ++++++ trunk/target/apidocs/index-all.html | 460 ++++++++++++ trunk/target/apidocs/index.html | 65 ++ trunk/target/apidocs/overview-tree.html | 137 ++++ trunk/target/apidocs/package-list | 1 + trunk/target/apidocs/resources/background.gif | Bin 0 -> 2313 bytes trunk/target/apidocs/resources/tab.gif | Bin 0 -> 291 bytes trunk/target/apidocs/resources/titlebar.gif | Bin 0 -> 10701 bytes .../target/apidocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes trunk/target/apidocs/stylesheet.css | 474 ++++++++++++ trunk/target/classes/LICENSE | 202 +++++ trunk/target/classes/NOTICE | 2 + .../com/googlecode/ipv6/BitSetHelpers.class | Bin 0 -> 838 bytes .../com/googlecode/ipv6/IPv6Address.class | Bin 0 -> 11074 bytes .../googlecode/ipv6/IPv6AddressHelpers.class | Bin 0 -> 4835 bytes .../googlecode/ipv6/IPv6AddressPool$1$1.class | Bin 0 -> 1660 bytes .../googlecode/ipv6/IPv6AddressPool$1.class | Bin 0 -> 976 bytes .../com/googlecode/ipv6/IPv6AddressPool.class | Bin 0 -> 10203 bytes .../googlecode/ipv6/IPv6AddressRange$1.class | Bin 0 -> 239 bytes ...ge$IPv6AddressRangeAsSubnetsIterator.class | Bin 0 -> 2714 bytes ...ddressRange$IPv6AddressRangeIterator.class | Bin 0 -> 1987 bytes .../googlecode/ipv6/IPv6AddressRange.class | Bin 0 -> 5909 bytes ...Pv6Network$IPv6NetworkSplitsIterator.class | Bin 0 -> 2545 bytes .../com/googlecode/ipv6/IPv6Network.class | Bin 0 -> 5053 bytes .../googlecode/ipv6/IPv6NetworkHelpers.class | Bin 0 -> 1122 bytes .../com/googlecode/ipv6/IPv6NetworkMask.class | Bin 0 -> 2726 bytes .../java-ipv6-0.16-SNAPSHOT-javadoc.jar | Bin 0 -> 78320 bytes .../java-ipv6-0.16-SNAPSHOT-sources.jar | Bin 0 -> 23816 bytes trunk/target/java-ipv6-0.16-SNAPSHOT.jar | Bin 0 -> 33116 bytes .../javadoc-options-javadoc-resources.xml | 10 + .../javadoc-bundle-options/package-list | 203 +++++ trunk/target/maven-archiver/pom.properties | 5 + ...om.googlecode.ipv6.IPv6AddressPoolTest.xml | 77 ++ ...m.googlecode.ipv6.IPv6AddressRangeTest.xml | 80 ++ ...ST-com.googlecode.ipv6.IPv6AddressTest.xml | 104 +++ ...googlecode.ipv6.IPv6NetworkHelpersTest.xml | 65 ++ ...om.googlecode.ipv6.IPv6NetworkMaskTest.xml | 68 ++ ...ST-com.googlecode.ipv6.IPv6NetworkTest.xml | 75 ++ ...om.googlecode.ipv6.IPv6AddressPoolTest.txt | 4 + ...m.googlecode.ipv6.IPv6AddressRangeTest.txt | 4 + .../com.googlecode.ipv6.IPv6AddressTest.txt | 4 + ...googlecode.ipv6.IPv6NetworkHelpersTest.txt | 4 + ...om.googlecode.ipv6.IPv6NetworkMaskTest.txt | 4 + .../com.googlecode.ipv6.IPv6NetworkTest.txt | 4 + .../googlecode/ipv6/IPv6AddressPoolTest.class | Bin 0 -> 7092 bytes .../ipv6/IPv6AddressRangeTest.class | Bin 0 -> 8418 bytes .../com/googlecode/ipv6/IPv6AddressTest.class | Bin 0 -> 11643 bytes .../ipv6/IPv6NetworkHelpersTest.class | Bin 0 -> 1057 bytes .../googlecode/ipv6/IPv6NetworkMaskTest.class | Bin 0 -> 1485 bytes .../com/googlecode/ipv6/IPv6NetworkTest.class | Bin 0 -> 5876 bytes .../googlecode/ipv6/examples/Examples.class | Bin 0 -> 5644 bytes wiki/WhatsNew.wiki | 33 + 803 files changed, 141018 insertions(+) create mode 100644 artifacts/0.1/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.1/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6Address.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6Network.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-frame.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-summary.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-tree.html create mode 100644 artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-use.html create mode 100644 artifacts/0.1/doc/apidocs/constant-values.html create mode 100644 artifacts/0.1/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.1/doc/apidocs/help-doc.html create mode 100644 artifacts/0.1/doc/apidocs/index-all.html create mode 100644 artifacts/0.1/doc/apidocs/index.html create mode 100644 artifacts/0.1/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.1/doc/apidocs/package-list create mode 100644 artifacts/0.1/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.1/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.1/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.1/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.1/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.10/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.10/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.10/doc/apidocs/constant-values.html create mode 100644 artifacts/0.10/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.10/doc/apidocs/help-doc.html create mode 100644 artifacts/0.10/doc/apidocs/index-all.html create mode 100644 artifacts/0.10/doc/apidocs/index.html create mode 100644 artifacts/0.10/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.10/doc/apidocs/package-list create mode 100644 artifacts/0.10/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.10/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.10/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.10/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.10/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.11/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.11/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.11/doc/apidocs/constant-values.html create mode 100644 artifacts/0.11/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.11/doc/apidocs/help-doc.html create mode 100644 artifacts/0.11/doc/apidocs/index-all.html create mode 100644 artifacts/0.11/doc/apidocs/index.html create mode 100644 artifacts/0.11/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.11/doc/apidocs/package-list create mode 100644 artifacts/0.11/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.11/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.11/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.11/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.11/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.12/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.12/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.12/doc/apidocs/constant-values.html create mode 100644 artifacts/0.12/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.12/doc/apidocs/help-doc.html create mode 100644 artifacts/0.12/doc/apidocs/index-all.html create mode 100644 artifacts/0.12/doc/apidocs/index.html create mode 100644 artifacts/0.12/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.12/doc/apidocs/package-list create mode 100644 artifacts/0.12/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.12/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.12/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.12/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.12/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.13/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.13/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.13/doc/apidocs/constant-values.html create mode 100644 artifacts/0.13/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.13/doc/apidocs/help-doc.html create mode 100644 artifacts/0.13/doc/apidocs/index-all.html create mode 100644 artifacts/0.13/doc/apidocs/index.html create mode 100644 artifacts/0.13/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.13/doc/apidocs/package-list create mode 100644 artifacts/0.13/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.13/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.13/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.13/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.13/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.14/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.14/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.14/doc/apidocs/constant-values.html create mode 100644 artifacts/0.14/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.14/doc/apidocs/help-doc.html create mode 100644 artifacts/0.14/doc/apidocs/index-all.html create mode 100644 artifacts/0.14/doc/apidocs/index.html create mode 100644 artifacts/0.14/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.14/doc/apidocs/package-list create mode 100644 artifacts/0.14/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.14/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.14/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.14/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.14/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.15/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.15/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.15/doc/apidocs/constant-values.html create mode 100644 artifacts/0.15/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.15/doc/apidocs/help-doc.html create mode 100644 artifacts/0.15/doc/apidocs/index-all.html create mode 100644 artifacts/0.15/doc/apidocs/index.html create mode 100644 artifacts/0.15/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.15/doc/apidocs/package-list create mode 100644 artifacts/0.15/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.15/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.15/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.15/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.15/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.2/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.2/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6Address.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6Network.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-frame.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-summary.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-tree.html create mode 100644 artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-use.html create mode 100644 artifacts/0.2/doc/apidocs/constant-values.html create mode 100644 artifacts/0.2/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.2/doc/apidocs/help-doc.html create mode 100644 artifacts/0.2/doc/apidocs/index-all.html create mode 100644 artifacts/0.2/doc/apidocs/index.html create mode 100644 artifacts/0.2/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.2/doc/apidocs/package-list create mode 100644 artifacts/0.2/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.2/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.2/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.2/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.2/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.3/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.3/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6Address.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6Network.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-frame.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-summary.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-tree.html create mode 100644 artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-use.html create mode 100644 artifacts/0.3/doc/apidocs/constant-values.html create mode 100644 artifacts/0.3/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.3/doc/apidocs/help-doc.html create mode 100644 artifacts/0.3/doc/apidocs/index-all.html create mode 100644 artifacts/0.3/doc/apidocs/index.html create mode 100644 artifacts/0.3/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.3/doc/apidocs/package-list create mode 100644 artifacts/0.3/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.3/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.3/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.3/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.3/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.4/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.4/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6Address.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6Network.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-frame.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-summary.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-tree.html create mode 100644 artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-use.html create mode 100644 artifacts/0.4/doc/apidocs/constant-values.html create mode 100644 artifacts/0.4/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.4/doc/apidocs/help-doc.html create mode 100644 artifacts/0.4/doc/apidocs/index-all.html create mode 100644 artifacts/0.4/doc/apidocs/index.html create mode 100644 artifacts/0.4/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.4/doc/apidocs/package-list create mode 100644 artifacts/0.4/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.4/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.4/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.4/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.4/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.5/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.5/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.5/doc/apidocs/constant-values.html create mode 100644 artifacts/0.5/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.5/doc/apidocs/help-doc.html create mode 100644 artifacts/0.5/doc/apidocs/index-all.html create mode 100644 artifacts/0.5/doc/apidocs/index.html create mode 100644 artifacts/0.5/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.5/doc/apidocs/package-list create mode 100644 artifacts/0.5/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.5/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.5/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.5/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.5/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.6/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.6/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.6/doc/apidocs/constant-values.html create mode 100644 artifacts/0.6/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.6/doc/apidocs/help-doc.html create mode 100644 artifacts/0.6/doc/apidocs/index-all.html create mode 100644 artifacts/0.6/doc/apidocs/index.html create mode 100644 artifacts/0.6/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.6/doc/apidocs/package-list create mode 100644 artifacts/0.6/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.6/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.6/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.6/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.6/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.7/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.7/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/BitSetHelpers.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/BitSetHelpers.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.7/doc/apidocs/constant-values.html create mode 100644 artifacts/0.7/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.7/doc/apidocs/help-doc.html create mode 100644 artifacts/0.7/doc/apidocs/index-all.html create mode 100644 artifacts/0.7/doc/apidocs/index.html create mode 100644 artifacts/0.7/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.7/doc/apidocs/package-list create mode 100644 artifacts/0.7/doc/apidocs/resources/inherit.gif create mode 100644 artifacts/0.7/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.8/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.8/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.8/doc/apidocs/constant-values.html create mode 100644 artifacts/0.8/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.8/doc/apidocs/help-doc.html create mode 100644 artifacts/0.8/doc/apidocs/index-all.html create mode 100644 artifacts/0.8/doc/apidocs/index.html create mode 100644 artifacts/0.8/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.8/doc/apidocs/package-list create mode 100644 artifacts/0.8/doc/apidocs/resources/inherit.gif create mode 100644 artifacts/0.8/doc/apidocs/stylesheet.css create mode 100644 artifacts/0.9/doc/apidocs/allclasses-frame.html create mode 100644 artifacts/0.9/doc/apidocs/allclasses-noframe.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 artifacts/0.9/doc/apidocs/constant-values.html create mode 100644 artifacts/0.9/doc/apidocs/deprecated-list.html create mode 100644 artifacts/0.9/doc/apidocs/help-doc.html create mode 100644 artifacts/0.9/doc/apidocs/index-all.html create mode 100644 artifacts/0.9/doc/apidocs/index.html create mode 100644 artifacts/0.9/doc/apidocs/overview-tree.html create mode 100644 artifacts/0.9/doc/apidocs/package-list create mode 100644 artifacts/0.9/doc/apidocs/resources/background.gif create mode 100644 artifacts/0.9/doc/apidocs/resources/tab.gif create mode 100644 artifacts/0.9/doc/apidocs/resources/titlebar.gif create mode 100644 artifacts/0.9/doc/apidocs/resources/titlebar_end.gif create mode 100644 artifacts/0.9/doc/apidocs/stylesheet.css create mode 100644 release.txt create mode 100644 tags/ipv6-0.1/pom.xml create mode 100644 tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6Address.java create mode 100644 tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java create mode 100644 tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressPool.java create mode 100644 tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressRange.java create mode 100644 tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6Network.java create mode 100644 tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/ipv6-0.1/src/test/java/be/jvb/ipv6/Examples.java create mode 100644 tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressTest.java create mode 100644 tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java create mode 100644 tags/ipv6-0.2/pom.xml create mode 100644 tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6Address.java create mode 100644 tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java create mode 100644 tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressPool.java create mode 100644 tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressRange.java create mode 100644 tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6Network.java create mode 100644 tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/ipv6-0.2/src/test/java/be/jvb/ipv6/Examples.java create mode 100644 tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressTest.java create mode 100644 tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java create mode 100644 tags/ipv6-0.3/pom.xml create mode 100644 tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6Address.java create mode 100644 tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java create mode 100644 tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressPool.java create mode 100644 tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressRange.java create mode 100644 tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6Network.java create mode 100644 tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/ipv6-0.3/src/test/java/be/jvb/ipv6/Examples.java create mode 100644 tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressTest.java create mode 100644 tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java create mode 100644 tags/ipv6-0.4/pom.xml create mode 100644 tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6Address.java create mode 100644 tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java create mode 100644 tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressPool.java create mode 100644 tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressRange.java create mode 100644 tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6Network.java create mode 100644 tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6NetworkMask.java create mode 100644 tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressTest.java create mode 100644 tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java create mode 100644 tags/ipv6-0.4/src/test/java/be/jvb/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.10/LICENSE create mode 100644 tags/java-ipv6-0.10/NOTICE create mode 100644 tags/java-ipv6-0.10/pom.xml create mode 100644 tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/BitSetHelpers.java create mode 100644 tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.11/LICENSE create mode 100644 tags/java-ipv6-0.11/NOTICE create mode 100644 tags/java-ipv6-0.11/pom.xml create mode 100644 tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/BitSetHelpers.java create mode 100644 tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.12/LICENSE create mode 100644 tags/java-ipv6-0.12/NOTICE create mode 100644 tags/java-ipv6-0.12/pom.xml create mode 100644 tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/BitSetHelpers.java create mode 100644 tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.13/LICENSE create mode 100644 tags/java-ipv6-0.13/NOTICE create mode 100644 tags/java-ipv6-0.13/pom.xml create mode 100644 tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/BitSetHelpers.java create mode 100644 tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.14/LICENSE create mode 100644 tags/java-ipv6-0.14/NOTICE create mode 100644 tags/java-ipv6-0.14/pom.xml create mode 100644 tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/BitSetHelpers.java create mode 100644 tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.15/LICENSE create mode 100644 tags/java-ipv6-0.15/NOTICE create mode 100644 tags/java-ipv6-0.15/pom.xml create mode 100644 tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/BitSetHelpers.java create mode 100644 tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.5/pom.xml create mode 100644 tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.6/pom.xml create mode 100644 tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.7/pom.xml create mode 100644 tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/BitSetHelpers.java create mode 100644 tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.8/pom.xml create mode 100644 tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/BitSetHelpers.java create mode 100644 tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 tags/java-ipv6-0.9/pom.xml create mode 100644 tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/BitSetHelpers.java create mode 100644 tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 trunk/LICENSE create mode 100644 trunk/NOTICE create mode 100644 trunk/pom.xml create mode 100644 trunk/src/main/java/com/googlecode/ipv6/BitSetHelpers.java create mode 100644 trunk/src/main/java/com/googlecode/ipv6/IPv6Address.java create mode 100644 trunk/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java create mode 100644 trunk/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java create mode 100644 trunk/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java create mode 100644 trunk/src/main/java/com/googlecode/ipv6/IPv6Network.java create mode 100644 trunk/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java create mode 100644 trunk/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java create mode 100644 trunk/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java create mode 100644 trunk/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java create mode 100644 trunk/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java create mode 100644 trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java create mode 100644 trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java create mode 100644 trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java create mode 100644 trunk/src/test/java/com/googlecode/ipv6/examples/Examples.java create mode 100644 trunk/target/apidocs/allclasses-frame.html create mode 100644 trunk/target/apidocs/allclasses-noframe.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/IPv6Address.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressPool.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressRange.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/IPv6Network.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/package-frame.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/package-summary.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/package-tree.html create mode 100644 trunk/target/apidocs/com/googlecode/ipv6/package-use.html create mode 100644 trunk/target/apidocs/constant-values.html create mode 100644 trunk/target/apidocs/deprecated-list.html create mode 100644 trunk/target/apidocs/help-doc.html create mode 100644 trunk/target/apidocs/index-all.html create mode 100644 trunk/target/apidocs/index.html create mode 100644 trunk/target/apidocs/overview-tree.html create mode 100644 trunk/target/apidocs/package-list create mode 100644 trunk/target/apidocs/resources/background.gif create mode 100644 trunk/target/apidocs/resources/tab.gif create mode 100644 trunk/target/apidocs/resources/titlebar.gif create mode 100644 trunk/target/apidocs/resources/titlebar_end.gif create mode 100644 trunk/target/apidocs/stylesheet.css create mode 100644 trunk/target/classes/LICENSE create mode 100644 trunk/target/classes/NOTICE create mode 100644 trunk/target/classes/com/googlecode/ipv6/BitSetHelpers.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6Address.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6AddressHelpers.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6AddressPool$1$1.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6AddressPool$1.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6AddressPool.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6AddressRange$1.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6AddressRange$IPv6AddressRangeAsSubnetsIterator.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6AddressRange$IPv6AddressRangeIterator.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6AddressRange.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6Network$IPv6NetworkSplitsIterator.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6Network.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6NetworkHelpers.class create mode 100644 trunk/target/classes/com/googlecode/ipv6/IPv6NetworkMask.class create mode 100644 trunk/target/java-ipv6-0.16-SNAPSHOT-javadoc.jar create mode 100644 trunk/target/java-ipv6-0.16-SNAPSHOT-sources.jar create mode 100644 trunk/target/java-ipv6-0.16-SNAPSHOT.jar create mode 100644 trunk/target/javadoc-bundle-options/javadoc-options-javadoc-resources.xml create mode 100644 trunk/target/javadoc-bundle-options/package-list create mode 100644 trunk/target/maven-archiver/pom.properties create mode 100644 trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressPoolTest.xml create mode 100644 trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressRangeTest.xml create mode 100644 trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressTest.xml create mode 100644 trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkHelpersTest.xml create mode 100644 trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkMaskTest.xml create mode 100644 trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkTest.xml create mode 100644 trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressPoolTest.txt create mode 100644 trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressRangeTest.txt create mode 100644 trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressTest.txt create mode 100644 trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkHelpersTest.txt create mode 100644 trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkMaskTest.txt create mode 100644 trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkTest.txt create mode 100644 trunk/target/test-classes/com/googlecode/ipv6/IPv6AddressPoolTest.class create mode 100644 trunk/target/test-classes/com/googlecode/ipv6/IPv6AddressRangeTest.class create mode 100644 trunk/target/test-classes/com/googlecode/ipv6/IPv6AddressTest.class create mode 100644 trunk/target/test-classes/com/googlecode/ipv6/IPv6NetworkHelpersTest.class create mode 100644 trunk/target/test-classes/com/googlecode/ipv6/IPv6NetworkMaskTest.class create mode 100644 trunk/target/test-classes/com/googlecode/ipv6/IPv6NetworkTest.class create mode 100644 trunk/target/test-classes/com/googlecode/ipv6/examples/Examples.class create mode 100644 wiki/WhatsNew.wiki diff --git a/artifacts/0.1/doc/apidocs/allclasses-frame.html b/artifacts/0.1/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..3d04896 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/allclasses-frame.html @@ -0,0 +1,24 @@ + + + + + + +All Classes (IPv6 0.2-SNAPSHOT API) + + + + +

All Classes

+
+ +
+ + diff --git a/artifacts/0.1/doc/apidocs/allclasses-noframe.html b/artifacts/0.1/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..e18cb63 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,24 @@ + + + + + + +All Classes (IPv6 0.2-SNAPSHOT API) + + + + +

All Classes

+
+ +
+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6Address.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6Address.html new file mode 100644 index 0000000..6e97397 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6Address.html @@ -0,0 +1,449 @@ + + + + + + +IPv6Address (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + + +
+
be.jvb.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..cc92da1 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + + +
+
be.jvb.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..903e273 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html @@ -0,0 +1,356 @@ + + + + + + +IPv6AddressPool (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + + +
+
be.jvb.ipv6
+

Class IPv6AddressPool

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..877bffe --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html @@ -0,0 +1,466 @@ + + + + + + +IPv6AddressRange (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + + +
+
be.jvb.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6Network.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6Network.html new file mode 100644 index 0000000..5ca2c10 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6Network.html @@ -0,0 +1,370 @@ + + + + + + +IPv6Network (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + + +
+
be.jvb.ipv6
+

Class IPv6Network

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..a7bd089 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + + +
+
be.jvb.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+ +
+
+ +
+
+ +
+
+ + +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..4428f1a --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html @@ -0,0 +1,253 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6Address (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Class
be.jvb.ipv6.IPv6Address

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..689ebec --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressHelpers (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressHelpers

+
+
No usage of be.jvb.ipv6.IPv6AddressHelpers
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..d435df1 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,154 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressPool (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressPool

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..a615de8 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,205 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressRange (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressRange

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..fae262d --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html @@ -0,0 +1,173 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6Network (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Class
be.jvb.ipv6.IPv6Network

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..0f0f85b --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6NetworkHelpers (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Class
be.jvb.ipv6.IPv6NetworkHelpers

+
+
No usage of be.jvb.ipv6.IPv6NetworkHelpers
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-frame.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-frame.html new file mode 100644 index 0000000..b7089f8 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-frame.html @@ -0,0 +1,25 @@ + + + + + + +be.jvb.ipv6 (IPv6 0.2-SNAPSHOT API) + + + + +

be.jvb.ipv6

+
+

Classes

+ +
+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-summary.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-summary.html new file mode 100644 index 0000000..b3f02f5 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-summary.html @@ -0,0 +1,165 @@ + + + + + + +be.jvb.ipv6 (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Package be.jvb.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-tree.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-tree.html new file mode 100644 index 0000000..4e4f219 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-tree.html @@ -0,0 +1,132 @@ + + + + + + +be.jvb.ipv6 Class Hierarchy (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package be.jvb.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-use.html b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-use.html new file mode 100644 index 0000000..5b0c88b --- /dev/null +++ b/artifacts/0.1/doc/apidocs/be/jvb/ipv6/package-use.html @@ -0,0 +1,150 @@ + + + + + + +Uses of Package be.jvb.ipv6 (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
be.jvb.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/constant-values.html b/artifacts/0.1/doc/apidocs/constant-values.html new file mode 100644 index 0000000..c7f5a6f --- /dev/null +++ b/artifacts/0.1/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/deprecated-list.html b/artifacts/0.1/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..16438ec --- /dev/null +++ b/artifacts/0.1/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/help-doc.html b/artifacts/0.1/doc/apidocs/help-doc.html new file mode 100644 index 0000000..07ffd2e --- /dev/null +++ b/artifacts/0.1/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+ +This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/index-all.html b/artifacts/0.1/doc/apidocs/index-all.html new file mode 100644 index 0000000..e4d2402 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/index-all.html @@ -0,0 +1,344 @@ + + + + + + +Index (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
A B C D E F G H I M O R S T  + + +

A

+
+
add(long) - Method in class be.jvb.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
+ + + +

B

+
+
be.jvb.ipv6 - package be.jvb.ipv6
+
 
+
+ + + +

C

+
+
compareTo(IPv6Address) - Method in class be.jvb.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
contains(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class be.jvb.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6Network
+
 
+
extend(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
fromInetAddress(InetAddress) - Static method in class be.jvb.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromString(String) - Static method in class be.jvb.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class be.jvb.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
getLast() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
getLowBits() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
getPrefixLength() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
+ + + +

I

+
+
IPv6Address - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in be.jvb.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressPool(IPv6Address, IPv6Address, int) - Constructor for class be.jvb.ipv6.IPv6AddressPool
+
+
Create a pool in between the given first and last address (inclusive) which is completely free.
+
+
IPv6AddressRange - Class in be.jvb.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6AddressRange(IPv6Address, IPv6Address) - Constructor for class be.jvb.ipv6.IPv6AddressRange
+
 
+
IPv6Network - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6Network(IPv6Address, int) - Constructor for class be.jvb.ipv6.IPv6Network
+
+
Construct from address and prefix length.
+
+
IPv6Network(IPv6Address, IPv6Address) - Constructor for class be.jvb.ipv6.IPv6Network
+
+
Construct from first and last address.
+
+
IPv6NetworkHelpers - Class in be.jvb.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class be.jvb.ipv6.IPv6NetworkHelpers
+
 
+
isExhausted() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
iterator() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
+ + + +

M

+
+
maskWithPrefixLength(int) - Method in class be.jvb.ipv6.IPv6Address
+
+
Mask the address with the given prefix length.
+
+
maximumAddressWithPrefixLength(int) - Method in class be.jvb.ipv6.IPv6Address
+
+
Calculate the maximum address with the given prefix length.
+
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
subtract(long) - Method in class be.jvb.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toInetAddress() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toShortArray() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
+A B C D E F G H I M O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/index.html b/artifacts/0.1/doc/apidocs/index.html new file mode 100644 index 0000000..c05b9eb --- /dev/null +++ b/artifacts/0.1/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +IPv6 0.2-SNAPSHOT API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="be/jvb/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.1/doc/apidocs/overview-tree.html b/artifacts/0.1/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..defea2e --- /dev/null +++ b/artifacts/0.1/doc/apidocs/overview-tree.html @@ -0,0 +1,136 @@ + + + + + + +Class Hierarchy (IPv6 0.2-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.1/doc/apidocs/package-list b/artifacts/0.1/doc/apidocs/package-list new file mode 100644 index 0000000..d2a5ec8 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/package-list @@ -0,0 +1 @@ +be.jvb.ipv6 diff --git a/artifacts/0.1/doc/apidocs/resources/background.gif b/artifacts/0.1/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.1/doc/apidocs/stylesheet.css b/artifacts/0.1/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.1/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.10/doc/apidocs/allclasses-frame.html b/artifacts/0.10/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..b9a1ac8 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.10 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.10/doc/apidocs/allclasses-noframe.html b/artifacts/0.10/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..18bf42f --- /dev/null +++ b/artifacts/0.10/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.10 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..8696cdb --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,515 @@ + + + + + + +IPv6Address (Java IPv6 Library 0.10 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        +
        Overrides:
        +
        toString in class Object
        +
        Returns:
        String representation of the IPv6 address, using shorthand notation whenever possible.
        +
      • +
      + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        String representation of the IPv6 address, never using shorthand notation.
        +
      • +
      + + + +
        +
      • +

        toShortArray

        +
        public short[] toShortArray()
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..e15b132 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.10 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..c253ba6 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,474 @@ + + + + + + +IPv6AddressPool (Java IPv6 Library 0.10 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromRangeAndSubnet

        +
        public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
        +                                 IPv6NetworkMask allocationSubnetSize)
        +
        Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size).
        +
        Parameters:
        range - range from within to allocate
        allocationSubnetSize - size of the subnets that will be allocated
        +
      • +
      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..a2077e7 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,467 @@ + + + + + + +IPv6AddressRange (Java IPv6 Library 0.10 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + +
        +
      • +

        compareTo

        +
        public int compareTo(IPv6AddressRange that)
        +
        The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal. +

        + Note that the natural order does thus not compare sizes of ranges.

        +
        +
        Specified by:
        +
        compareTo in interface Comparable<IPv6AddressRange>
        +
        Parameters:
        that - range to compare with
        +
        Returns:
        negative, zero or positive depending on whether this is smaller, equal or greater than that
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..99aebfc --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,368 @@ + + + + + + +IPv6Network (Java IPv6 Library 0.10 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddressAndMask

        +
        public static IPv6Network fromAddressAndMask(IPv6Address address,
        +                             IPv6NetworkMask networkMask)
        +
        Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
        +
        Parameters:
        address - IPv6 address (the network address or any other address within the network)
        networkMask - IPv6 network mask
        +
        Returns:
        IPv6 network
        +
      • +
      + + + +
        +
      • +

        fromTwoAddresses

        +
        public static IPv6Network fromTwoAddresses(IPv6Address one,
        +                           IPv6Address two)
        +
        Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses.
        +
        Parameters:
        one - address one
        two - address two, should be bigger than address one
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 network
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        +
        Overrides:
        +
        toLongString in class IPv6AddressRange
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..edd0e69 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.10 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..fb365ca --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,328 @@ + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.10 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddress

        +
        public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        Parameters:
        iPv6Address - address to use as network mask
        +
        Throws:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        fromPrefixLength

        +
        public static IPv6NetworkMask fromPrefixLength(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        Parameters:
        prefixLength - prefix length
        +
        Throws:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      + + + +
        +
      • +

        asPrefixLength

        +
        public int asPrefixLength()
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..1d20658 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,263 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.10 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..7ebc10d --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.10 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+
No usage of com.googlecode.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..b58b5b5 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,161 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.10 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..b5c2d97 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,222 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.10 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..c747120 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,204 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.10 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..bbeda26 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.10 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+
No usage of com.googlecode.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..9d28619 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,187 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.10 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..0475b27 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.10 API) + + + + +

com.googlecode.ipv6

+ + + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..c4296eb --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.10 API) + + + + + + + + + + +
+

Package com.googlecode.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..b24e3c9 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.10 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package com.googlecode.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..b7f4da0 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.10 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
com.googlecode.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/constant-values.html b/artifacts/0.10/doc/apidocs/constant-values.html new file mode 100644 index 0000000..73d8fec --- /dev/null +++ b/artifacts/0.10/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (Java IPv6 Library 0.10 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/deprecated-list.html b/artifacts/0.10/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..e5713d7 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (Java IPv6 Library 0.10 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/help-doc.html b/artifacts/0.10/doc/apidocs/help-doc.html new file mode 100644 index 0000000..d6762d2 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (Java IPv6 Library 0.10 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The Constant Field Values page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/index-all.html b/artifacts/0.10/doc/apidocs/index-all.html new file mode 100644 index 0000000..15efe1a --- /dev/null +++ b/artifacts/0.10/doc/apidocs/index-all.html @@ -0,0 +1,405 @@ + + + + + + +Index (Java IPv6 Library 0.10 API) + + + + + + + +
+ + + + + +
+ + +
A C D E F G H I M N O R S T  + + +

A

+
+
add(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
+
 
+
compareTo(IPv6Address) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal.
+
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
fromAddress(IPv6Address) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+
+
fromFirstAndLast(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
fromInetAddress(InetAddress) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromPrefixLength(int) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Create a pool of the given range (boundaries inclusive) which is completely free.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
fromTwoAddresses(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from the two addresses within the network.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getNetmask() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressRange - Class in com.googlecode.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6Network - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6NetworkHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network mask.
+
+
isExhausted() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
iterator() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
+ + + +

N

+
+
numberOfLeadingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
subtract(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toInetAddress() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toShortArray() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+A C D E F G H I M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/index.html b/artifacts/0.10/doc/apidocs/index.html new file mode 100644 index 0000000..4d80eb1 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +Java IPv6 Library 0.10 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="com/googlecode/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.10/doc/apidocs/overview-tree.html b/artifacts/0.10/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..d9cc0ea --- /dev/null +++ b/artifacts/0.10/doc/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +Class Hierarchy (Java IPv6 Library 0.10 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.10/doc/apidocs/package-list b/artifacts/0.10/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.10/doc/apidocs/resources/background.gif b/artifacts/0.10/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.10/doc/apidocs/stylesheet.css b/artifacts/0.10/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.10/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.11/doc/apidocs/allclasses-frame.html b/artifacts/0.11/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..5b51a04 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.11 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.11/doc/apidocs/allclasses-noframe.html b/artifacts/0.11/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..09239ef --- /dev/null +++ b/artifacts/0.11/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.11 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..dab45e3 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,554 @@ + + + + + + +IPv6Address (Java IPv6 Library 0.11 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromLongs

        +
        public static IPv6Address fromLongs(long highBits,
        +                    long lowBits)
        +
        Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + IPv6Addresses from a String or an InetAddress. The internal representation of an IPv6Address is exactly + these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address.
        +
        Parameters:
        highBits - highest order bits
        lowBits - lowest order bits
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        fromByteArray

        +
        public static IPv6Address fromByteArray(byte[] bytes)
        +
        Create an IPv6 address from a byte array.
        +
        Parameters:
        bytes - byte array with 16 bytes
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        toByteArray

        +
        public byte[] toByteArray()
        +
      • +
      + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        +
        Overrides:
        +
        toString in class Object
        +
        Returns:
        String representation of the IPv6 address, using shorthand notation whenever possible.
        +
      • +
      + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        String representation of the IPv6 address, never using shorthand notation.
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..df2d101 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.11 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..62a2f5d --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,474 @@ + + + + + + +IPv6AddressPool (Java IPv6 Library 0.11 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromRangeAndSubnet

        +
        public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
        +                                 IPv6NetworkMask allocationSubnetSize)
        +
        Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size).
        +
        Parameters:
        range - range from within to allocate
        allocationSubnetSize - size of the subnets that will be allocated
        +
      • +
      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..f1a6d5d --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,467 @@ + + + + + + +IPv6AddressRange (Java IPv6 Library 0.11 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + +
        +
      • +

        compareTo

        +
        public int compareTo(IPv6AddressRange that)
        +
        The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal. +

        + Note that the natural order does thus not compare sizes of ranges.

        +
        +
        Specified by:
        +
        compareTo in interface Comparable<IPv6AddressRange>
        +
        Parameters:
        that - range to compare with
        +
        Returns:
        negative, zero or positive depending on whether this is smaller, equal or greater than that
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..73c63e4 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,368 @@ + + + + + + +IPv6Network (Java IPv6 Library 0.11 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddressAndMask

        +
        public static IPv6Network fromAddressAndMask(IPv6Address address,
        +                             IPv6NetworkMask networkMask)
        +
        Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
        +
        Parameters:
        address - IPv6 address (the network address or any other address within the network)
        networkMask - IPv6 network mask
        +
        Returns:
        IPv6 network
        +
      • +
      + + + +
        +
      • +

        fromTwoAddresses

        +
        public static IPv6Network fromTwoAddresses(IPv6Address one,
        +                           IPv6Address two)
        +
        Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses.
        +
        Parameters:
        one - address one
        two - address two, should be bigger than address one
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 network
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        +
        Overrides:
        +
        toLongString in class IPv6AddressRange
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..8d34d00 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.11 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..eb53dbf --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,328 @@ + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.11 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddress

        +
        public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        Parameters:
        iPv6Address - address to use as network mask
        +
        Throws:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        fromPrefixLength

        +
        public static IPv6NetworkMask fromPrefixLength(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        Parameters:
        prefixLength - prefix length
        +
        Throws:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      + + + +
        +
      • +

        asPrefixLength

        +
        public int asPrefixLength()
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..0eed9b2 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,276 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.11 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..0c3ef43 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.11 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+
No usage of com.googlecode.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..044b89a --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,161 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.11 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..7c9115d --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,222 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.11 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..906440c --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,204 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.11 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..bebf9e1 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.11 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+
No usage of com.googlecode.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..68d2624 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,187 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.11 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..b275e0f --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.11 API) + + + + +

com.googlecode.ipv6

+ + + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..af6dfbc --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.11 API) + + + + + + + + + + +
+

Package com.googlecode.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..211ab54 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.11 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package com.googlecode.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..8bf5025 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.11 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
com.googlecode.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/constant-values.html b/artifacts/0.11/doc/apidocs/constant-values.html new file mode 100644 index 0000000..f008d19 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (Java IPv6 Library 0.11 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/deprecated-list.html b/artifacts/0.11/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..bfdd05c --- /dev/null +++ b/artifacts/0.11/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (Java IPv6 Library 0.11 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/help-doc.html b/artifacts/0.11/doc/apidocs/help-doc.html new file mode 100644 index 0000000..ac17c75 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (Java IPv6 Library 0.11 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The Constant Field Values page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/index-all.html b/artifacts/0.11/doc/apidocs/index-all.html new file mode 100644 index 0000000..51dd2f1 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/index-all.html @@ -0,0 +1,413 @@ + + + + + + +Index (Java IPv6 Library 0.11 API) + + + + + + + +
+ + + + + +
+ + +
A C D E F G H I M N O R S T  + + +

A

+
+
add(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
+
 
+
compareTo(IPv6Address) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal.
+
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
fromAddress(IPv6Address) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+
+
fromByteArray(byte[]) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a byte array.
+
+
fromFirstAndLast(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
fromInetAddress(InetAddress) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromLongs(long, long) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits.
+
+
fromPrefixLength(int) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Create a pool of the given range (boundaries inclusive) which is completely free.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
fromTwoAddresses(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from the two addresses within the network.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getNetmask() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressRange - Class in com.googlecode.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6Network - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6NetworkHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network mask.
+
+
isExhausted() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
iterator() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
+ + + +

N

+
+
numberOfLeadingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
subtract(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toByteArray() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toInetAddress() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+A C D E F G H I M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/index.html b/artifacts/0.11/doc/apidocs/index.html new file mode 100644 index 0000000..5d5550d --- /dev/null +++ b/artifacts/0.11/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +Java IPv6 Library 0.11 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="com/googlecode/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.11/doc/apidocs/overview-tree.html b/artifacts/0.11/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..52b2e10 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +Class Hierarchy (Java IPv6 Library 0.11 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.11/doc/apidocs/package-list b/artifacts/0.11/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.11/doc/apidocs/resources/background.gif b/artifacts/0.11/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 zX3B0NWXQ443Eo1rUP86rLU>O>oTp%wt3Z{Tz&P*)Iraq^_@X;RtUFY!JxH|4U!>kw zxXwqo&R3Y=EsXaR!ng@y+y$%L1P3FZ4@N!j3m5MW74HcC->_JFuvlxLXiI=-OQ2|@ zpGc#>2-aN)<1RE9^`bB0`65VSK2>5m>CHs^YZCC)NX*NfbeT1%)Cxpu2_(6cCbLvjLY`hf1%*q}QO*%V4SfOu5Nqg~`-+(-76= za<`RA&(qDB^S!nIS^od5|Nk$KPXD8(qSB!f`M*{E?A^&yOW$08V^iNPK!%UNJ-@xmz>`pG2_%4I3QWk4UdtwP!GH$C%mo2K|$Ap=_)Y!#O($1@ohsUtR1k%wI*) z4*X&g==oWh`j{uP=HFm;Ye>0>UbDdtSp^~MaQ!L9I#)Ga?q}{@T#|qec*FkMLDenm zj^sCgk!^O^3o|vG!~2$$$7`C#4Ry zdQ!tui+J1*HyavK+4{`r+zvYHj9IsRt~@uEBOreWS8~2rXAR3!|7aTdr+x4|>@$Az z)b1t$gSB~6USxpfLmy^|_J_eNt*PI=ScO1SVH895N#`ef%IOh&o-2GIjK1s-JzkyZ z@r7O%hChz}kMHCM@Wqi^R-9t&%Fh^#9dVB0%ej@$=OjXA%XZdzCXf}c>SW26_z-Te z5b{}XWg&rELM=N*%aimp)k04t2c+`WAS>ZFIPWKvtyOI))HzpRA!T!b{tv?4NzF1v zNlP%#{&p@lFFEKvcroMAsI)mq?&`!e%l+-y&j9ZqhN}oG&dB=Pw09r+Q%m0cMujS# zs$a7!9VH`CC7k{!bV(J`rm%Jpj6&nLtWhPcy$onn$8G#ZdD9hxO<9k67Ya>K_7W~3 z&KYf14fq<{qHA7u6;>AOcomhdg?ianjr9uINt}*7w?g%z9{Q`(qRo@hDwSpGmxz&h&>%G%T(URL~=c>C{>y$K?+wLFp zy*M1@FTUKYV>8DeDIAIKM+!T5c-k&C4?Y~y^E zQCIc-=9~DiPtfVZB=_c3`qH3h|NXd^BcOQG`funSe)i5!NoA_r{b6PwzSDIXG+!(F z9CqJgo&~#7^VZHWj{u23q+NDCHn}GeWDC*(SW%{f4WMtP3l2jsO7*M)EX)#NLlsNnU4q@#jn0r#rsWsf^ngE0&ambG1f;Rj zfOk#_>1|25Z%?iI{0Yv8)DQfk>m1td?~}m0N%^k^u%EuUCc#ItmlY|epQ3YLWehYw zRU0qpPb#X&WU*UOU8et(s8x~WyYWYsgJCF+;U6@*nICY8)dk}IG+(#_Bz8zURd3HZ6qPE68U1%S{wL0 z;K{PDw2iRFIGG?(UiE9kT9?siuv4O{ z`dX2-eiXU3N)H2nT4V=AO^~J}sw+gr{&~qx%$$wlMv_JCWAMfcjYl}*Cfcf!adOY8 z8oLmJ{%49e+nLiVo#H9}wRk?UCzDz^>9TDxreVHzl~R*)?YU>Uu;J2eQ27O5`&X^8 z`94{)YWJQa#l0Fbz0N6B>j&8J;<%VuG6OYM9&QIdtueWjI3X;*dEtGiF@1AcvN4U> zG5SXIEXxB>)!mtQOztJLyeF78S*kLiU-!>PtQ_s~OMl~&y(hVVe$A5 zwo}E-DJ6${QP75?LsQ}Wl@MXwXMT4d>|?rD!g?jE>J^N*y;X}5FLe%d0_ zZ>eIBK6l@jkfw{p_YiDP;MS{jww{%j#?rk2z1J!HqE;Vd!TrCl_7UPef8;edI}wD6 zT&12Bxj&q}d4%$GHq+$~UYtWv`wI9k`89oKkCEK_E;-+O)(rhThjOM|kXDn{!W1Lo z`_?yQv=lp=-w()R<=0&c5%RWHY_fw@qb}uwFuPAGkl~@Kis}eE%MY@~6ZyWcF+llM zGyK`)(vn1F%%z=W7-Y=1$`w0Mv+-|#d};%JjCmw)Y1hOxwA|{}P%6LS4X`jQCGh`mR@=hGrr|cXa^Ipj;Mh)6mTqd1s_HmP0IxXT!w7YhoIHT>Hm#!;c@|L9OjV zsTlHE{Z;HWeM9^tPm-`|&nnl$%DRtNG1~?npUvgKPwKlaccEe4q!7YU3zykJnu6Sr z()LMXs_)^~u-ds7+wMff)RAJF?2?1H`_wDnt%MssYeB5;q~ojgVm6OHA6B>FG2erv z8&`|6<`=!EPKR^8Qlp5MiKwfxy4D`mN> ze$RKh_6*YJd4y0nnUZvwN%iY&^9xk@cM|5g#pZkc#N*(PH?^w&?ilTDMXFcd0`5!E zvgHS`=Lc|~1aO=L@L~eE*aP{90lc7qXY7GOs)3JH14T{(`K1D%tpvUT1-?F^1d4_S zJ#7yXkP3Q37bJlRQfv=mV-J3B8O*m5B%L3uW)S>|Jwy`|s6iK`sv0Z-3NcU(0knrG z5ChFXA@A9PUSdLI+(VU!!J1Mbw!~0VP^jZci2X|Nx0BF!24ObrAr>b=QtlyN4TAhn z!mQncJm~^m4MIafVLt_ewDUtO+e5w*!`(6A&H^F7i9s4t5&uBpNvh$nlTZjqTM5krNRRQ zqP)VR!|9@H>7qN_!+-)&_9s!^;gOvy5s~iEB&qP8{77&2NJMzZcsnJgSt_bYDzYU% zxQ#uuk3D*e7_*d5^?HW(^(WxICGf-mcmM((VStzIz%zFsm0;ZI3h=5OciJ#a%7I(IeGbFv+PP^?^sKBPrRBl<+qK^o%3fi=L9`la>-l4~p|hzAl~W zf=%(|NHgF7r5dJD+Cf08q-c(m;Epsldaz4cqHzTHT>)4xEe(cE0i~tf{Y0xs_1~Kv z+BYQ-TpEOch13;5YC9nHYEXhSv{ew=LV~nQL%UBQEgaDL2m?9u~v zEQmOvM=aB)Z$+eE38rs%AZR_)4>@2raqwH#Fji#xoLc&PS_TU^W8W(M0GqLdO~1yF z{sfHZ_sC#FX58(}d>RSkKZCz8%D7{cC3Z$Zh@52{31&V*W-@s~Z<8~aBeNcNW?e&O zsR(7fHOf}B&fsRqdZ(WK1e~s*o^uD6{YX9QJvqyWAqQXt*E>r$V94YK=X@8+{1cg> z*_i`a%alCJvbD~lCg&Q1Gk=|BzY)sejf9EHJ{s7lu4?ExCWR3jgTiET;exy{sW!Mg zuj*_YOf0@ScN~X0$7V6&KpL172rf|rA8?K<2+GelXw)NUk#@b4aT5MO%1ip4*ym}B-JI__S1R?CK z<4eW~bH;@H@tR55x}&JNSw_NvEPk)6E>XDt7*)4sgWuw+_vNZzmaS(tsi(57zcjA9 z@~XcHtzYq~IX|z*Md9mh>W~`sk3<^s7;EmyH4wcTdAo5NkUA2ofeG69{Gx7#i_*lt zQ7;N@xEo#nNRj&SbDHNnP0w#OE0{DZ$~7ySG%IN~zwd5Vu4&dnH>*OMb>&*VL^tbA zG;7y1t9dsYU$p3pw0x6mwGe6fjBYWsZ8e3q8f~-~cefgHxBangajI$kv(c*W-DZGp zbM$UgnP{_MYPXYX|6$u^deIhE(-xuGX2RVXqS+o~(iSV%;ZW1=Zqkut(r&xak^pT> zsp*I@X|-eOd^gb+sM(%3(E$|c47Y91mTU99Xe;4vFOTl5gmwVB+fvc3n2pwK?~Xd# zwrY{?CUj@~Msr?wXU0WKv2A$hq z`$V^gNq4(<*C=;4e4}$*uIC$5&uUHkM08J~N$>VV*VpdmLCuc!?!J9=-)VH;fo9)| zNN4m#^Kb9|`RF!^ZAT-z=bC8$do8~Tjc^o-aQjyc2(TW*d50E1#NW0pKb^~tf&OUlS+W}>0!m@!~1 z&TdSLhm`0u99c-z=oxYL8IFaGCDoFwFUP!1iJ%xF1UC4hhv*VR2451Pc0+kQGC)39C5 za81oV=$+xzZNYhn=RB-CTZ>Bevj)A3mi9|OS(dcy=N#Zm=Dza|z4Jd<=3IQ2CB>FiwH7{4Ej#+oa>M67 z!56)Km&2xJ|H7B;%~rJDuJ{rbZQiaX*e^$DEt~T$#h9(y#jg6>uX?boq!N}Q;EQth zYo1rjc15dETPw~*Ymu=lreoE9g^wb)ZcRe1yp1(Eo(rmqUYZXOU$BC_| zX{{&qE?E06wXm#v#cpKwE)jaydSaI`TkCCClr_lKMzPkyFT!R%VRn&sZSrchKx&4e~pJQcfViQxxl=T=7}#gYz7Pvoh`T#Jbab%2A2m zxh?A<`}A?8_GumBEcL;$x%gQb@PZ(If%ZE~D?ax#Km4a~+GV~!;Bb~qxxh@HHc|H6 zr%$^c9Dw~UQFWJv+81rCXS1vqqLfQ~-BtO63xCArGVA4T-}xPXYGHqB5h^+n5%$24 z(BROpi13J@*qFfR$oRMHel`=(zy zovs-UKHD3VkJ?hVeq!aA+8Fh4+NIlFhcC~UrR{4I#}K*u&z%68+P1*=q0B1r*2MY> z!9gYs*vlTO5v#8S>c#3goFmp>3iVKdU)NkjNV(s7tO4Wq?2M}o5Cj-*7;S=fEshOA zR*4$dm{ROvUamG%xL_tSW6}U$Nl=@91T;nC11o-iIVyVrfkd) zTCp;^tOy|_kuOFV$Nn=$AQJO9;&sZ&eDs^!r*m;Hw!)vpO1vcfj2EV{dJ?7ap0tq6 z$SwUVM*Vt+MS_`;bas-svPV|3POQi8G~?f^KOx4hg1He+Wd*s3Hl1{TfJS-+zv6vc zPoKiwr?7wECbub(IdB)9f_!kmUjBR*KY_z4E8_QA9xSr#G&@i5y^H`jB^I{|akh>W z%Cn3luOVY|8P>u>e^~#{$kmgX&-q>k{#pFbm2({(rtG<%nb0UCQ0%{Cy`F&~7}*we z@Of>ND_)V&XwN_+n~KjVorUQWZ*B6cld7ymQl{;rwlHl34K#}2YWxE+4CX@P&u6AfCda`&ZT1MOY69e-L@gNcAvwx8%1Z7lB4zc=_Cpt~&s ze%?;){1DB(PSK!^za967qF?lIjB~&06}Lf`cgh2qUiI^|$-VCTNE=hp&Ij}^A9&|* zQQrSqo3gn#_=z9j(y6f@T|OkJYv(fjwpz}$*U$|nLH2F zPNMuTS4g8 z*^hOlRh6~Mk}58;d477R>F^~aLO$dOXmhA*6zwIaHK()t2zKjo?j^NOJbh_=+71xg zO{Mgp7x?Z-1MKzoQ<+V2g#|e}|JawOPJZBL{o~PYdtWDX?jl##!Aiq|w>)vGJLipp zBK1xGhcvgSsQ;rn>+`>UmxlID{<~}7{y>SO^cyktN^Fsz!Z|B4?p*RKQG*8}SYBt{ zuFO{vJ?jgL{gUzYsnv(io}c0vlCp#*1vE?}KL^UZ&VF^TK+D;40CxX%j);%dCt;Z{ zAeMXC9JPWvKGwsCxx4w2iv_wNGG8l16AVI93rmc^c1>r(P||YE zpXa+=-&k995hfykL^J5S&vJF^ljR&`FE#ppNMM3%Omc!F)Mn{{&Ip#)JegbEJxud2 zn`wDVB~DMii5|H%m~51YeU1juNG3!+&?*uC#q@)z8q~`4yEL5I8}PtyA1IZ=52P$x zX)KhZt z7czUXBsy-8d`GVQ`90`wIh(Xt7v5j7h0t&ET~2M!Tb~4rN-xtK@8@mB*c(6QTwOS- z%9445_WY|cfm4?$nX$72&{~^mu}an^x^Da%=UU6YI;ur3+9L6I>raW5!=-Nzy(F2Z zwZlg7aM3NN5b{K|FB>s4R}|&Lr32_Ys{wwkECxo|rV@;5aHB25iUs7(6@dDpjN{Y%?C~UGp>*Q}K?)KKk64 zAn;@-dER}QG0L${jQ1cR75eM3-~ZTltTQ8%sm9x4Y`ve@ekMuvpA#Rh51@s6;6^&Q z!&M7^b%cea7FlZkPV9}@!bPBBfB&~XvGlE2T7V?IpM~OBmuK;OSt{~N`rL5c_I^de z9n*=@p|l;d`b_YIn8Aem1t7pp0=2-MCTIcJHlY z6x+mNLgi{JpwP)y(yzAFL2A#>bI&EwZE`PGvd*FQ!rx~6bUN&+Ij3)L;=595L#G;m8*^e?ap1`J5w7-q)*iUT_W9w8 z&xS-`i++HpWzY-a-)CWd0(pLW$A85P{Dy9r-=uPekNpN^yA}pJ7yWTZ>3iw4d6+IK zF%1XXkGcJm{0*vhSG5R1ySW;jctk9O==1-Mk?=Bl<{HE1p_@tx1s^+GoczYxj#B=i=kwQvEPrOt`<4W*pJw zbNjEqpr7B|Llc%m{V*QssV)im;pb00LUob=yFaU4`P_}ywU zt*QZl-bUsmh@L&zQaX4uHL&7YD(BOb9hH;;y;O-b-_O$4EFi1vCrMlz`dN|u?}HNO^aFQV{UZg_yy%nf>IXpulip!cR8|vNu7P*; zQye@}Qmj%(TB6`5E=c~w=LITF266XJ6X5xA7!OM1SE=~N*o3EP5Qqx!W<_+EMSLGo zqkC18AQ=0AK9=hgGQtrTovYc5^?Z^RLX?hlO-j&e1MXTTbfm>MS^=}!p>C>icUKdZ zBcNOb(6IJ!kq*e7N8Fx!!kPyn+2B2^2hd00+W^PUA&+S63jFE)bP5Tv+L5l~n(pu? zbeO|+K{{?pEow3?j0+dGVu)a6(0r{1Uj7{3 zxSsZ|BdMk>1-S}-;+`pk{Q5>H=tLRx+YqeenaSRsEX@gtPzz>j1A9g!C9kGtspY(- z%YL>NkVDE2z@}*;Q{=&5)yS;NupAmmibGUE4qte7aY6PcnXJgw>}ad(SW;@HtNurF ziV0_yHz=;Di%Tki6DW^tjkL`t%Ktct(ay zvuAOYoCu!Pm~@P5CIjk$bp`_iv{^l*Au{fB8mJK1>Macv?GL)**8*+JNvySIH5Y7i#1;!%NT!efc z;Z0*AOM&1VpR+6wIQxBM{xf`8T1V@#e<#QL}=YRwMkWG8%1(Fgj{iX)N zup{Txko(DqJWf=#Oi?Z!nra-?C{);TP`w|4>L+EKx1&P3swX<*#_50F!lD_$nQyuK??!UwA-{y)^QmMxoK1xIJ~uML{u;5!Z5tQyEL>;KaUd!_9FP zl2$QOI6V1`QdF|8gkdZsSpUqCjSBu(1H)r*vL#PEy)@Px>5TIk7_9o#Bj zzD&<1_k(ejk%qO6ak=GMmG5b7LTAA^KKq-Ey#z8(2wy2;Ot^oZI(MG@)~iY$RAnJt zu`ioyvR?Vws_tuK9hDqmel+)bP0kyxJV{7t=&3{b(@Hs1fs$9n45aq)IKknZa2H*7 z^P-ZDyOMdMj&-9{(-?dqo5I3Gy=K$!L%q>3^0N~o^2i0^_@^2nQv>S4B&=5_8^a^V zaY!NjyA5QgO&r#^CJcp&=!))MZ*CC&hvLEzWU*!IO=aYo{_yG+53H$XOAIQWnG`uD zLuuwTY6e8N^m5^AHQa}Y5Z#SdbEY;+x{oW?g;ie4CNYomRyQd2mv^L}T!>a5<*wTh>@>Qtwp~nejn`~DcZJI+QC-xU zoxz=5z0k%1;jBrGI%Th~FQElrAPr?E-Fv9|o09dPk=?>f)jFKL8PK|;w(cVDq>YWP zEfL7RGBv|<>f4IccND3wCi*V8`>#a$FPZu&a{V`W`me+Kuf_CJ)%IV%?5ByL^#3Q{ z&uBM5|34IKI>0_Tz{5OngXe#6w*N6;;5PH%9n%56%RaWA{wJ4%515Apdj`a62bp<> zM12OuV+QZ^55ATkViO(UWgg}%9C}kb^r~=BiDyWIXZWM&kb>Q?dd$#W`4KU|2#4qh zz;sZ>ZqS5h#Kdk$&1c9AHmDUdtmHE)CqH0RIAZEE;t(^+RXF+*FlJyk;?6Vn{&MsO zZ0HwY)b4Va!F1#s^N5$-s9(&mPa*Lu4>4SxXm~l|3?PR2jB1J!Q|(4#0i$lFME^-r zA~Q(2O+PHOdcVN((R8zqi>%+yx4PA5u&+jI zZ?)Fm8m-+`n!Bnrx0PvZE7!Q)Z+NTE@K(R!nO40sZF(n~bq_b_9H`UYU#q>pPJ3UC z_UeU>J7qcy%%`ks9)BNcS^GDOn z?oKkjHNoWO1e2?M#vd12e^_AscAnLnc~-CISiYWX`D%{k^H~<37unpMYJYdSv=Om2vbAM@`Qp{{SI=yP zj6WN*eEt0G$9EPX6FU%)-ho>hWTW!yzXBIo73<0umM-=@eG&niY^` zlG(|vuCl_x(X^Fob@=i{8+M5vWf7Bz=#aHGTNA;fZQyfbfueI8Z^639n`(DI%w^-^ zl`=@!u)r~Xf920-xd$Ab+S&PJY%K0H8a_J8uN3^_!K1_NV$*e#*Y*6|)XpiW=9H`*`Xx7W%v@7{XDma1?v0a%(K6rI&1!a YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.11/doc/apidocs/stylesheet.css b/artifacts/0.11/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.11/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.12/doc/apidocs/allclasses-frame.html b/artifacts/0.12/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..818a66c --- /dev/null +++ b/artifacts/0.12/doc/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.12 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.12/doc/apidocs/allclasses-noframe.html b/artifacts/0.12/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..13c344e --- /dev/null +++ b/artifacts/0.12/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.12 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..8da63b3 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,618 @@ + + + + + + +IPv6Address (Java IPv6 Library 0.12 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromLongs

        +
        public static IPv6Address fromLongs(long highBits,
        +                    long lowBits)
        +
        Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + IPv6Addresses from a String or an InetAddress. The internal representation of an IPv6Address is exactly + these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address.
        +
        Parameters:
        highBits - highest order bits
        lowBits - lowest order bits
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::". IPv4-Mapped IPv6 addresses such as "::ffff:123.456.123.456" are also supported.
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        fromByteArray

        +
        public static IPv6Address fromByteArray(byte[] bytes)
        +
        Create an IPv6 address from a byte array.
        +
        Parameters:
        bytes - byte array with 16 bytes
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        toByteArray

        +
        public byte[] toByteArray()
        +
      • +
      + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        isIPv4Mapped

        +
        public boolean isIPv4Mapped()
        +
        Returns true if the address is an IPv4-mapped IPv6 address. In these addresses, the first 80 bits are zero, the next 16 bits are one, + and the remaining 32 bits are the IPv4 address.
        +
        Returns:
        true if the address is an IPv4-mapped IPv6 addresses.
        +
      • +
      + + + +
        +
      • +

        isMulticast

        +
        public boolean isMulticast()
        +
        Returns:
        true if the address is an IPv6 multicast address (an address in the network ff00::/8)
        +
      • +
      + + + +
        +
      • +

        isSiteLocal

        +
        public boolean isSiteLocal()
        +
        Returns:
        true if the address is an IPv6 site-local address (an address in the network fec0::/48)
        +
      • +
      + + + +
        +
      • +

        isLinkLocal

        +
        public boolean isLinkLocal()
        +
        Returns:
        true if the address is an IPv6 link-local address (an address in the network fe80::/48)
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        Returns a string representation of the IPv6 address. It will use shorthand notation and special notation for IPv4-mapped IPv6 + addresses whenever possible.
        +
        +
        Overrides:
        +
        toString in class Object
        +
        Returns:
        String representation of the IPv6 address
        +
      • +
      + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        String representation of the IPv6 address, never using shorthand notation.
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..5fcebcc --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.12 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..52c7994 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,474 @@ + + + + + + +IPv6AddressPool (Java IPv6 Library 0.12 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromRangeAndSubnet

        +
        public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
        +                                 IPv6NetworkMask allocationSubnetSize)
        +
        Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size).
        +
        Parameters:
        range - range from within to allocate
        allocationSubnetSize - size of the subnets that will be allocated
        +
      • +
      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..590ef8b --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,467 @@ + + + + + + +IPv6AddressRange (Java IPv6 Library 0.12 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + +
        +
      • +

        compareTo

        +
        public int compareTo(IPv6AddressRange that)
        +
        The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal. +

        + Note that the natural order does thus not compare sizes of ranges.

        +
        +
        Specified by:
        +
        compareTo in interface Comparable<IPv6AddressRange>
        +
        Parameters:
        that - range to compare with
        +
        Returns:
        negative, zero or positive depending on whether this is smaller, equal or greater than that
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..4c51c8c --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,368 @@ + + + + + + +IPv6Network (Java IPv6 Library 0.12 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddressAndMask

        +
        public static IPv6Network fromAddressAndMask(IPv6Address address,
        +                             IPv6NetworkMask networkMask)
        +
        Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
        +
        Parameters:
        address - IPv6 address (the network address or any other address within the network)
        networkMask - IPv6 network mask
        +
        Returns:
        IPv6 network
        +
      • +
      + + + +
        +
      • +

        fromTwoAddresses

        +
        public static IPv6Network fromTwoAddresses(IPv6Address one,
        +                           IPv6Address two)
        +
        Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses.
        +
        Parameters:
        one - address one
        two - address two, should be bigger than address one
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 network
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        +
        Overrides:
        +
        toLongString in class IPv6AddressRange
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..c67f67c --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.12 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..a7a2905 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,328 @@ + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.12 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddress

        +
        public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        Parameters:
        iPv6Address - address to use as network mask
        +
        Throws:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        fromPrefixLength

        +
        public static IPv6NetworkMask fromPrefixLength(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        Parameters:
        prefixLength - prefix length
        +
        Throws:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      + + + +
        +
      • +

        asPrefixLength

        +
        public int asPrefixLength()
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..ac7b06f --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,276 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.12 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..93855e4 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.12 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+
No usage of com.googlecode.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..23e077d --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,161 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.12 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..5508dfb --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,222 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.12 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..4987e4a --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,204 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.12 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..1ec355d --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.12 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+
No usage of com.googlecode.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..a1d63bd --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,187 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.12 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..4f3d0bc --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.12 API) + + + + +

com.googlecode.ipv6

+ + + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..a09d8e6 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.12 API) + + + + + + + + + + +
+

Package com.googlecode.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..1764f40 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.12 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package com.googlecode.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..ede1269 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.12 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
com.googlecode.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/constant-values.html b/artifacts/0.12/doc/apidocs/constant-values.html new file mode 100644 index 0000000..85024f8 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (Java IPv6 Library 0.12 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/deprecated-list.html b/artifacts/0.12/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..4143ecc --- /dev/null +++ b/artifacts/0.12/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (Java IPv6 Library 0.12 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/help-doc.html b/artifacts/0.12/doc/apidocs/help-doc.html new file mode 100644 index 0000000..13cbada --- /dev/null +++ b/artifacts/0.12/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (Java IPv6 Library 0.12 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The Constant Field Values page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/index-all.html b/artifacts/0.12/doc/apidocs/index-all.html new file mode 100644 index 0000000..ac04f52 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/index-all.html @@ -0,0 +1,425 @@ + + + + + + +Index (Java IPv6 Library 0.12 API) + + + + + + + +
+ + + + + +
+ + +
A C D E F G H I M N O R S T  + + +

A

+
+
add(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
+
 
+
compareTo(IPv6Address) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal.
+
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
fromAddress(IPv6Address) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+
+
fromByteArray(byte[]) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a byte array.
+
+
fromFirstAndLast(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
fromInetAddress(InetAddress) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromLongs(long, long) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits.
+
+
fromPrefixLength(int) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Create a pool of the given range (boundaries inclusive) which is completely free.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
fromTwoAddresses(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from the two addresses within the network.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getNetmask() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressRange - Class in com.googlecode.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6Network - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6NetworkHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network mask.
+
+
isExhausted() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isIPv4Mapped() - Method in class com.googlecode.ipv6.IPv6Address
+
+
Returns true if the address is an IPv4-mapped IPv6 address.
+
+
isLinkLocal() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
isMulticast() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
isSiteLocal() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
iterator() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
+ + + +

N

+
+
numberOfLeadingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
subtract(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toByteArray() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toInetAddress() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Address
+
+
Returns a string representation of the IPv6 address.
+
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+A C D E F G H I M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/index.html b/artifacts/0.12/doc/apidocs/index.html new file mode 100644 index 0000000..7b2dec3 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +Java IPv6 Library 0.12 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="com/googlecode/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.12/doc/apidocs/overview-tree.html b/artifacts/0.12/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..aa2a9a3 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +Class Hierarchy (Java IPv6 Library 0.12 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.12/doc/apidocs/package-list b/artifacts/0.12/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.12/doc/apidocs/resources/background.gif b/artifacts/0.12/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.12/doc/apidocs/stylesheet.css b/artifacts/0.12/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.12/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.13/doc/apidocs/allclasses-frame.html b/artifacts/0.13/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..e7bcacc --- /dev/null +++ b/artifacts/0.13/doc/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.13 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.13/doc/apidocs/allclasses-noframe.html b/artifacts/0.13/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..4c77813 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.13 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..7cd3171 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,618 @@ + + + + + + +IPv6Address (Java IPv6 Library 0.13 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromLongs

        +
        public static IPv6Address fromLongs(long highBits,
        +                    long lowBits)
        +
        Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + IPv6Addresses from a String or an InetAddress. The internal representation of an IPv6Address is exactly + these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address.
        +
        Parameters:
        highBits - highest order bits
        lowBits - lowest order bits
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::". IPv4-Mapped IPv6 addresses such as "::ffff:123.456.123.456" are also supported.
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        fromByteArray

        +
        public static IPv6Address fromByteArray(byte[] bytes)
        +
        Create an IPv6 address from a byte array.
        +
        Parameters:
        bytes - byte array with 16 bytes
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        toByteArray

        +
        public byte[] toByteArray()
        +
      • +
      + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        isIPv4Mapped

        +
        public boolean isIPv4Mapped()
        +
        Returns true if the address is an IPv4-mapped IPv6 address. In these addresses, the first 80 bits are zero, the next 16 bits are one, + and the remaining 32 bits are the IPv4 address.
        +
        Returns:
        true if the address is an IPv4-mapped IPv6 addresses.
        +
      • +
      + + + +
        +
      • +

        isMulticast

        +
        public boolean isMulticast()
        +
        Returns:
        true if the address is an IPv6 multicast address (an address in the network ff00::/8)
        +
      • +
      + + + +
        +
      • +

        isSiteLocal

        +
        public boolean isSiteLocal()
        +
        Returns:
        true if the address is an IPv6 site-local address (an address in the network fec0::/48)
        +
      • +
      + + + +
        +
      • +

        isLinkLocal

        +
        public boolean isLinkLocal()
        +
        Returns:
        true if the address is an IPv6 link-local address (an address in the network fe80::/48)
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        Returns a string representation of the IPv6 address. It will use shorthand notation and special notation for IPv4-mapped IPv6 + addresses whenever possible.
        +
        +
        Overrides:
        +
        toString in class Object
        +
        Returns:
        String representation of the IPv6 address
        +
      • +
      + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        String representation of the IPv6 address, never using shorthand notation.
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..48ba0e5 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.13 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..cc03bf4 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,474 @@ + + + + + + +IPv6AddressPool (Java IPv6 Library 0.13 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromRangeAndSubnet

        +
        public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
        +                                 IPv6NetworkMask allocationSubnetSize)
        +
        Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size).
        +
        Parameters:
        range - range from within to allocate
        allocationSubnetSize - size of the subnets that will be allocated
        +
      • +
      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..459165a --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,467 @@ + + + + + + +IPv6AddressRange (Java IPv6 Library 0.13 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + +
        +
      • +

        compareTo

        +
        public int compareTo(IPv6AddressRange that)
        +
        The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal. +

        + Note that the natural order does thus not compare sizes of ranges.

        +
        +
        Specified by:
        +
        compareTo in interface Comparable<IPv6AddressRange>
        +
        Parameters:
        that - range to compare with
        +
        Returns:
        negative, zero or positive depending on whether this is smaller, equal or greater than that
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..7f6f9d8 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,430 @@ + + + + + + +IPv6Network (Java IPv6 Library 0.13 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Field Detail

      + + + +
        +
      • +

        MULTICAST_NETWORK

        +
        public static final IPv6Network MULTICAST_NETWORK
        +
      • +
      + + + +
        +
      • +

        SITE_LOCAL_NETWORK

        +
        public static final IPv6Network SITE_LOCAL_NETWORK
        +
      • +
      + + + +
        +
      • +

        LINK_LOCAL_NETWORK

        +
        public static final IPv6Network LINK_LOCAL_NETWORK
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddressAndMask

        +
        public static IPv6Network fromAddressAndMask(IPv6Address address,
        +                             IPv6NetworkMask networkMask)
        +
        Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
        +
        Parameters:
        address - IPv6 address (the network address or any other address within the network)
        networkMask - IPv6 network mask
        +
        Returns:
        IPv6 network
        +
      • +
      + + + +
        +
      • +

        fromTwoAddresses

        +
        public static IPv6Network fromTwoAddresses(IPv6Address one,
        +                           IPv6Address two)
        +
        Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses.
        +
        Parameters:
        one - address one
        two - address two, should be bigger than address one
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 network
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        +
        Overrides:
        +
        toLongString in class IPv6AddressRange
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..3c1a7ab --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.13 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..1406cb5 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,328 @@ + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.13 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddress

        +
        public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        Parameters:
        iPv6Address - address to use as network mask
        +
        Throws:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        fromPrefixLength

        +
        public static IPv6NetworkMask fromPrefixLength(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        Parameters:
        prefixLength - prefix length
        +
        Throws:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      + + + +
        +
      • +

        asPrefixLength

        +
        public int asPrefixLength()
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..bd54a81 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,276 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.13 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..516ce6a --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.13 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+
No usage of com.googlecode.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..16f83f6 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,161 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.13 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..2df1748 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,222 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.13 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..dd8886d --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,225 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.13 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..b6ec79c --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.13 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+
No usage of com.googlecode.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..aa5210e --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,187 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.13 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..e0e8a45 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.13 API) + + + + +

com.googlecode.ipv6

+ + + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..4ad6f9c --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.13 API) + + + + + + + + + + +
+

Package com.googlecode.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..238b60c --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.13 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package com.googlecode.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..2715cda --- /dev/null +++ b/artifacts/0.13/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.13 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
com.googlecode.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/constant-values.html b/artifacts/0.13/doc/apidocs/constant-values.html new file mode 100644 index 0000000..d08a3bc --- /dev/null +++ b/artifacts/0.13/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (Java IPv6 Library 0.13 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/deprecated-list.html b/artifacts/0.13/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..c788ac6 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (Java IPv6 Library 0.13 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/help-doc.html b/artifacts/0.13/doc/apidocs/help-doc.html new file mode 100644 index 0000000..a2af4b0 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (Java IPv6 Library 0.13 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The Constant Field Values page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/index-all.html b/artifacts/0.13/doc/apidocs/index-all.html new file mode 100644 index 0000000..632f674 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/index-all.html @@ -0,0 +1,437 @@ + + + + + + +Index (Java IPv6 Library 0.13 API) + + + + + + + +
+ + + + + +
+ + +
A C D E F G H I L M N O R S T  + + +

A

+
+
add(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
+
 
+
compareTo(IPv6Address) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal.
+
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
fromAddress(IPv6Address) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+
+
fromByteArray(byte[]) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a byte array.
+
+
fromFirstAndLast(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
fromInetAddress(InetAddress) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromLongs(long, long) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits.
+
+
fromPrefixLength(int) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Create a pool of the given range (boundaries inclusive) which is completely free.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
fromTwoAddresses(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from the two addresses within the network.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getNetmask() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressRange - Class in com.googlecode.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6Network - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6NetworkHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network mask.
+
+
isExhausted() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isIPv4Mapped() - Method in class com.googlecode.ipv6.IPv6Address
+
+
Returns true if the address is an IPv4-mapped IPv6 address.
+
+
isLinkLocal() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
isMulticast() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
isSiteLocal() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
iterator() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

L

+
+
LINK_LOCAL_NETWORK - Static variable in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
MULTICAST_NETWORK - Static variable in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

N

+
+
numberOfLeadingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
SITE_LOCAL_NETWORK - Static variable in class com.googlecode.ipv6.IPv6Network
+
 
+
subtract(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toByteArray() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toInetAddress() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Address
+
+
Returns a string representation of the IPv6 address.
+
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+A C D E F G H I L M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/index.html b/artifacts/0.13/doc/apidocs/index.html new file mode 100644 index 0000000..a851b11 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +Java IPv6 Library 0.13 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="com/googlecode/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.13/doc/apidocs/overview-tree.html b/artifacts/0.13/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..eea36a3 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +Class Hierarchy (Java IPv6 Library 0.13 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.13/doc/apidocs/package-list b/artifacts/0.13/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.13/doc/apidocs/resources/background.gif b/artifacts/0.13/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.13/doc/apidocs/stylesheet.css b/artifacts/0.13/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.13/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.14/doc/apidocs/allclasses-frame.html b/artifacts/0.14/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..21cc9d6 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.14 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.14/doc/apidocs/allclasses-noframe.html b/artifacts/0.14/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..0219e8b --- /dev/null +++ b/artifacts/0.14/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.14 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..3caca70 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,707 @@ + + + + + + +IPv6Address (Java IPv6 Library 0.14 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + + + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromLongs

        +
        public static IPv6Address fromLongs(long highBits,
        +                    long lowBits)
        +
        Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + IPv6Addresses from a String or an InetAddress. The internal representation of an IPv6Address is exactly + these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address.
        +
        Parameters:
        highBits - highest order bits
        lowBits - lowest order bits
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::". IPv4-Mapped IPv6 addresses such as "::ffff:123.456.123.456" are also supported.
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        fromByteArray

        +
        public static IPv6Address fromByteArray(byte[] bytes)
        +
        Create an IPv6 address from a byte array.
        +
        Parameters:
        bytes - byte array with 16 bytes (interpreted unsigned)
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        toByteArray

        +
        public byte[] toByteArray()
        +
        Returns:
        byte[] representation
        +
      • +
      + + + +
        +
      • +

        fromBigInteger

        +
        public static IPv6Address fromBigInteger(BigInteger bigInteger)
        +
        Create an IPv6 address from a (positive) BigInteger. The magnitude of the BigInteger represents + the IPv6 address value. Or in other words, the BigInteger with value N defines the Nth possible IPv6 address.
        +
        Parameters:
        bigInteger - BigInteger value
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        toBigInteger

        +
        public BigInteger toBigInteger()
        +
        Returns:
        BigInteger representation. The magnitude of the BigInteger represents the IPv6 address + value. Or in other words, the BigInteger with value N defines the Nth possible IPv6 address.
        +
      • +
      + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        setBit

        +
        public IPv6Address setBit(int bit)
        +
        Set a bit in the address.
        +
        Parameters:
        bit - to set (in the range [0, 127])
        +
        Returns:
        an address with the given bit set
        +
      • +
      + + + +
        +
      • +

        isIPv4Mapped

        +
        public boolean isIPv4Mapped()
        +
        Returns true if the address is an IPv4-mapped IPv6 address. In these addresses, the first 80 bits are zero, the next 16 bits are one, + and the remaining 32 bits are the IPv4 address.
        +
        Returns:
        true if the address is an IPv4-mapped IPv6 addresses.
        +
      • +
      + + + +
        +
      • +

        isMulticast

        +
        public boolean isMulticast()
        +
        Returns:
        true if the address is an IPv6 multicast address (an address in the network ff00::/8)
        +
      • +
      + + + +
        +
      • +

        isSiteLocal

        +
        public boolean isSiteLocal()
        +
        Returns:
        true if the address is an IPv6 site-local address (an address in the network fec0::/48)
        +
      • +
      + + + +
        +
      • +

        isLinkLocal

        +
        public boolean isLinkLocal()
        +
        Returns:
        true if the address is an IPv6 link-local address (an address in the network fe80::/48)
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        Returns a string representation of the IPv6 address. It will use shorthand notation and special notation for IPv4-mapped IPv6 + addresses whenever possible.
        +
        +
        Overrides:
        +
        toString in class Object
        +
        Returns:
        String representation of the IPv6 address
        +
      • +
      + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        String representation of the IPv6 address, never using shorthand notation.
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..e46fdfe --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.14 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..fcaa492 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,474 @@ + + + + + + +IPv6AddressPool (Java IPv6 Library 0.14 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromRangeAndSubnet

        +
        public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
        +                                 IPv6NetworkMask allocationSubnetSize)
        +
        Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size).
        +
        Parameters:
        range - range from within to allocate
        allocationSubnetSize - size of the subnets that will be allocated
        +
      • +
      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..543da64 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,480 @@ + + + + + + +IPv6AddressRange (Java IPv6 Library 0.14 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + +
        +
      • +

        compareTo

        +
        public int compareTo(IPv6AddressRange that)
        +
        The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal. +

        + Note that the natural order does thus not compare sizes of ranges.

        +
        +
        Specified by:
        +
        compareTo in interface Comparable<IPv6AddressRange>
        +
        Parameters:
        that - range to compare with
        +
        Returns:
        negative, zero or positive depending on whether this is smaller, equal or greater than that
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..1fbde50 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,450 @@ + + + + + + +IPv6Network (Java IPv6 Library 0.14 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Field Detail

      + + + +
        +
      • +

        MULTICAST_NETWORK

        +
        public static final IPv6Network MULTICAST_NETWORK
        +
      • +
      + + + +
        +
      • +

        SITE_LOCAL_NETWORK

        +
        public static final IPv6Network SITE_LOCAL_NETWORK
        +
      • +
      + + + +
        +
      • +

        LINK_LOCAL_NETWORK

        +
        public static final IPv6Network LINK_LOCAL_NETWORK
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddressAndMask

        +
        public static IPv6Network fromAddressAndMask(IPv6Address address,
        +                             IPv6NetworkMask networkMask)
        +
        Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
        +
        Parameters:
        address - IPv6 address (the network address or any other address within the network)
        networkMask - IPv6 network mask
        +
        Returns:
        IPv6 network
        +
      • +
      + + + +
        +
      • +

        fromTwoAddresses

        +
        public static IPv6Network fromTwoAddresses(IPv6Address one,
        +                           IPv6Address two)
        +
        Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses.
        +
        Parameters:
        one - address one
        two - address two, should be bigger than address one
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 network
        +
      • +
      + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        +
        Overrides:
        +
        toLongString in class IPv6AddressRange
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..5c4f6fe --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.14 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..ee474b8 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,328 @@ + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.14 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddress

        +
        public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        Parameters:
        iPv6Address - address to use as network mask
        +
        Throws:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        fromPrefixLength

        +
        public static IPv6NetworkMask fromPrefixLength(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        Parameters:
        prefixLength - prefix length
        +
        Throws:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      + + + +
        +
      • +

        asPrefixLength

        +
        public int asPrefixLength()
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..c2ab860 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,301 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.14 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..1a316fe --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.14 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+
No usage of com.googlecode.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..3644f36 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,161 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.14 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..6b7a55c --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,222 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.14 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..87a4a1c --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,231 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.14 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..d7b1ea2 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.14 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+
No usage of com.googlecode.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..f638e44 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,193 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.14 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..cce4a1f --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.14 API) + + + + +

com.googlecode.ipv6

+ + + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..35cc2ff --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.14 API) + + + + + + + + + + +
+

Package com.googlecode.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..cce668d --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.14 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package com.googlecode.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..014e3c2 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.14 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
com.googlecode.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/constant-values.html b/artifacts/0.14/doc/apidocs/constant-values.html new file mode 100644 index 0000000..a1695e9 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (Java IPv6 Library 0.14 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/deprecated-list.html b/artifacts/0.14/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..63f320f --- /dev/null +++ b/artifacts/0.14/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (Java IPv6 Library 0.14 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/help-doc.html b/artifacts/0.14/doc/apidocs/help-doc.html new file mode 100644 index 0000000..4211009 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (Java IPv6 Library 0.14 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The Constant Field Values page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/index-all.html b/artifacts/0.14/doc/apidocs/index-all.html new file mode 100644 index 0000000..b16eea1 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/index-all.html @@ -0,0 +1,455 @@ + + + + + + +Index (Java IPv6 Library 0.14 API) + + + + + + + +
+ + + + + +
+ + +
A C D E F G H I L M N O R S T  + + +

A

+
+
add(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
+
 
+
compareTo(IPv6Address) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal.
+
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
fromAddress(IPv6Address) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+
+
fromBigInteger(BigInteger) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a (positive) BigInteger.
+
+
fromByteArray(byte[]) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a byte array.
+
+
fromFirstAndLast(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
fromInetAddress(InetAddress) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromLongs(long, long) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits.
+
+
fromPrefixLength(int) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Create a pool of the given range (boundaries inclusive) which is completely free.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
fromTwoAddresses(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from the two addresses within the network.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getNetmask() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressRange - Class in com.googlecode.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6Network - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6NetworkHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network mask.
+
+
isExhausted() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isIPv4Mapped() - Method in class com.googlecode.ipv6.IPv6Address
+
+
Returns true if the address is an IPv4-mapped IPv6 address.
+
+
isLinkLocal() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
isMulticast() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
isSiteLocal() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
iterator() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

L

+
+
LINK_LOCAL_NETWORK - Static variable in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
MAX - Static variable in class com.googlecode.ipv6.IPv6Address
+
 
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
MULTICAST_NETWORK - Static variable in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

N

+
+
numberOfLeadingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
setBit(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Set a bit in the address.
+
+
SITE_LOCAL_NETWORK - Static variable in class com.googlecode.ipv6.IPv6Network
+
 
+
size() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
split(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Network
+
+
Split a network in smaller subnets of a given size.
+
+
subtract(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toBigInteger() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toByteArray() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toInetAddress() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Address
+
+
Returns a string representation of the IPv6 address.
+
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+A C D E F G H I L M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/index.html b/artifacts/0.14/doc/apidocs/index.html new file mode 100644 index 0000000..16a5c04 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +Java IPv6 Library 0.14 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="com/googlecode/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.14/doc/apidocs/overview-tree.html b/artifacts/0.14/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..c7c16a2 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +Class Hierarchy (Java IPv6 Library 0.14 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.14/doc/apidocs/package-list b/artifacts/0.14/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.14/doc/apidocs/resources/background.gif b/artifacts/0.14/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.14/doc/apidocs/stylesheet.css b/artifacts/0.14/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.14/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.15/doc/apidocs/allclasses-frame.html b/artifacts/0.15/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..5dbc21e --- /dev/null +++ b/artifacts/0.15/doc/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.15 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.15/doc/apidocs/allclasses-noframe.html b/artifacts/0.15/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..c658870 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.15 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..96372c2 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,707 @@ + + + + + + +IPv6Address (Java IPv6 Library 0.15 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + + + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromLongs

        +
        public static IPv6Address fromLongs(long highBits,
        +                    long lowBits)
        +
        Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + IPv6Addresses from a String or an InetAddress. The internal representation of an IPv6Address is exactly + these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address.
        +
        Parameters:
        highBits - highest order bits
        lowBits - lowest order bits
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::". IPv4-Mapped IPv6 addresses such as "::ffff:123.456.123.456" are also supported.
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        fromByteArray

        +
        public static IPv6Address fromByteArray(byte[] bytes)
        +
        Create an IPv6 address from a byte array.
        +
        Parameters:
        bytes - byte array with 16 bytes (interpreted unsigned)
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        toByteArray

        +
        public byte[] toByteArray()
        +
        Returns:
        byte[] representation
        +
      • +
      + + + +
        +
      • +

        fromBigInteger

        +
        public static IPv6Address fromBigInteger(BigInteger bigInteger)
        +
        Create an IPv6 address from a (positive) BigInteger. The magnitude of the BigInteger represents + the IPv6 address value. Or in other words, the BigInteger with value N defines the Nth possible IPv6 address.
        +
        Parameters:
        bigInteger - BigInteger value
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        toBigInteger

        +
        public BigInteger toBigInteger()
        +
        Returns:
        BigInteger representation. The magnitude of the BigInteger represents the IPv6 address + value. Or in other words, the BigInteger with value N defines the Nth possible IPv6 address.
        +
      • +
      + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        setBit

        +
        public IPv6Address setBit(int bit)
        +
        Set a bit in the address.
        +
        Parameters:
        bit - to set (in the range [0, 127])
        +
        Returns:
        an address with the given bit set
        +
      • +
      + + + +
        +
      • +

        isIPv4Mapped

        +
        public boolean isIPv4Mapped()
        +
        Returns true if the address is an IPv4-mapped IPv6 address. In these addresses, the first 80 bits are zero, the next 16 bits are one, + and the remaining 32 bits are the IPv4 address.
        +
        Returns:
        true if the address is an IPv4-mapped IPv6 addresses.
        +
      • +
      + + + +
        +
      • +

        isMulticast

        +
        public boolean isMulticast()
        +
        Returns:
        true if the address is an IPv6 multicast address (an address in the network ff00::/8)
        +
      • +
      + + + +
        +
      • +

        isSiteLocal

        +
        public boolean isSiteLocal()
        +
        Returns:
        true if the address is an IPv6 site-local address (an address in the network fec0::/48)
        +
      • +
      + + + +
        +
      • +

        isLinkLocal

        +
        public boolean isLinkLocal()
        +
        Returns:
        true if the address is an IPv6 link-local address (an address in the network fe80::/48)
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        Returns a string representation of the IPv6 address. It will use shorthand notation and special notation for IPv4-mapped IPv6 + addresses whenever possible.
        +
        +
        Overrides:
        +
        toString in class Object
        +
        Returns:
        String representation of the IPv6 address
        +
      • +
      + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        String representation of the IPv6 address, never using shorthand notation.
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..2502bac --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.15 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..0351eea --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,474 @@ + + + + + + +IPv6AddressPool (Java IPv6 Library 0.15 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromRangeAndSubnet

        +
        public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
        +                                 IPv6NetworkMask allocationSubnetSize)
        +
        Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size).
        +
        Parameters:
        range - range from within to allocate
        allocationSubnetSize - size of the subnets that will be allocated
        +
      • +
      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..067fc91 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,500 @@ + + + + + + +IPv6AddressRange (Java IPv6 Library 0.15 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        size

        +
        public BigInteger size()
        +
        Returns:
        number of addresses in the range
        +
      • +
      + + + +
        +
      • +

        toSubnets

        +
        public Iterator<IPv6Network> toSubnets()
        +
        Deaggregate a range of IPv6 addresses (which is not necessarily aligned with a single IPv6 network) into a minimal set of non + overlapping consecutive subnets.
        +
        Returns:
        iterator of IPv6 networks that all together define the minimal set of subnets by which the range can be represented.
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + +
        +
      • +

        compareTo

        +
        public int compareTo(IPv6AddressRange that)
        +
        The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal. +

        + Note that the natural order does thus not compare sizes of ranges.

        +
        +
        Specified by:
        +
        compareTo in interface Comparable<IPv6AddressRange>
        +
        Parameters:
        that - range to compare with
        +
        Returns:
        negative, zero or positive depending on whether this is smaller, equal or greater than that
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..ae361bb --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,450 @@ + + + + + + +IPv6Network (Java IPv6 Library 0.15 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Field Detail

      + + + +
        +
      • +

        MULTICAST_NETWORK

        +
        public static final IPv6Network MULTICAST_NETWORK
        +
      • +
      + + + +
        +
      • +

        SITE_LOCAL_NETWORK

        +
        public static final IPv6Network SITE_LOCAL_NETWORK
        +
      • +
      + + + +
        +
      • +

        LINK_LOCAL_NETWORK

        +
        public static final IPv6Network LINK_LOCAL_NETWORK
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddressAndMask

        +
        public static IPv6Network fromAddressAndMask(IPv6Address address,
        +                             IPv6NetworkMask networkMask)
        +
        Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
        +
        Parameters:
        address - IPv6 address (the network address or any other address within the network)
        networkMask - IPv6 network mask
        +
        Returns:
        IPv6 network
        +
      • +
      + + + +
        +
      • +

        fromTwoAddresses

        +
        public static IPv6Network fromTwoAddresses(IPv6Address one,
        +                           IPv6Address two)
        +
        Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses.
        +
        Parameters:
        one - address one
        two - address two, should be bigger than address one
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 network
        +
      • +
      + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        +
        Overrides:
        +
        toLongString in class IPv6AddressRange
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..da62f24 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.15 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..6f69437 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,328 @@ + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.15 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddress

        +
        public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        Parameters:
        iPv6Address - address to use as network mask
        +
        Throws:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        fromPrefixLength

        +
        public static IPv6NetworkMask fromPrefixLength(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        Parameters:
        prefixLength - prefix length
        +
        Throws:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      + + + +
        +
      • +

        asPrefixLength

        +
        public int asPrefixLength()
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..61d906d --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,301 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.15 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..b10a430 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.15 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+
No usage of com.googlecode.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..48edee6 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,161 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.15 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..2ab4533 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,222 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.15 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..672a0ef --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,238 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.15 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..a830813 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.15 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+
No usage of com.googlecode.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..da417f8 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,193 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.15 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..e81292c --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.15 API) + + + + +

com.googlecode.ipv6

+ + + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..7bc6e2f --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.15 API) + + + + + + + + + + +
+

Package com.googlecode.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..f3edcb9 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.15 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package com.googlecode.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..f5a38a1 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.15 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
com.googlecode.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/constant-values.html b/artifacts/0.15/doc/apidocs/constant-values.html new file mode 100644 index 0000000..d627b47 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (Java IPv6 Library 0.15 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/deprecated-list.html b/artifacts/0.15/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..b01fac7 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (Java IPv6 Library 0.15 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/help-doc.html b/artifacts/0.15/doc/apidocs/help-doc.html new file mode 100644 index 0000000..f6fe1b5 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (Java IPv6 Library 0.15 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The Constant Field Values page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/index-all.html b/artifacts/0.15/doc/apidocs/index-all.html new file mode 100644 index 0000000..30d977a --- /dev/null +++ b/artifacts/0.15/doc/apidocs/index-all.html @@ -0,0 +1,460 @@ + + + + + + +Index (Java IPv6 Library 0.15 API) + + + + + + + +
+ + + + + +
+ + +
A C D E F G H I L M N O R S T  + + +

A

+
+
add(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
+
 
+
compareTo(IPv6Address) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal.
+
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
fromAddress(IPv6Address) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+
+
fromBigInteger(BigInteger) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a (positive) BigInteger.
+
+
fromByteArray(byte[]) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a byte array.
+
+
fromFirstAndLast(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
fromInetAddress(InetAddress) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromLongs(long, long) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits.
+
+
fromPrefixLength(int) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Create a pool of the given range (boundaries inclusive) which is completely free.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
fromTwoAddresses(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from the two addresses within the network.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getNetmask() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressRange - Class in com.googlecode.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6Network - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6NetworkHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network mask.
+
+
isExhausted() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isIPv4Mapped() - Method in class com.googlecode.ipv6.IPv6Address
+
+
Returns true if the address is an IPv4-mapped IPv6 address.
+
+
isLinkLocal() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
isMulticast() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
isSiteLocal() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
iterator() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

L

+
+
LINK_LOCAL_NETWORK - Static variable in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
MAX - Static variable in class com.googlecode.ipv6.IPv6Address
+
 
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
MULTICAST_NETWORK - Static variable in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

N

+
+
numberOfLeadingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
setBit(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Set a bit in the address.
+
+
SITE_LOCAL_NETWORK - Static variable in class com.googlecode.ipv6.IPv6Network
+
 
+
size() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
split(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Network
+
+
Split a network in smaller subnets of a given size.
+
+
subtract(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toBigInteger() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toByteArray() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toInetAddress() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Address
+
+
Returns a string representation of the IPv6 address.
+
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
toSubnets() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Deaggregate a range of IPv6 addresses (which is not necessarily aligned with a single IPv6 network) into a minimal set of non + overlapping consecutive subnets.
+
+
+A C D E F G H I L M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/index.html b/artifacts/0.15/doc/apidocs/index.html new file mode 100644 index 0000000..0b5f51c --- /dev/null +++ b/artifacts/0.15/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +Java IPv6 Library 0.15 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="com/googlecode/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.15/doc/apidocs/overview-tree.html b/artifacts/0.15/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..d52c594 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +Class Hierarchy (Java IPv6 Library 0.15 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.15/doc/apidocs/package-list b/artifacts/0.15/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.15/doc/apidocs/resources/background.gif b/artifacts/0.15/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.15/doc/apidocs/stylesheet.css b/artifacts/0.15/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.15/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.2/doc/apidocs/allclasses-frame.html b/artifacts/0.2/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..4b4ce38 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/allclasses-frame.html @@ -0,0 +1,24 @@ + + + + + + +All Classes (IPv6 0.2 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.2/doc/apidocs/allclasses-noframe.html b/artifacts/0.2/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..3684fa4 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,24 @@ + + + + + + +All Classes (IPv6 0.2 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6Address.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6Address.html new file mode 100644 index 0000000..d884f1a --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6Address.html @@ -0,0 +1,449 @@ + + + + + + +IPv6Address (IPv6 0.2 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        add

        +
        public IPv6Address add(long value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(long value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithPrefixLength

        +
        public IPv6Address maskWithPrefixLength(int prefixLength)
        +
        Mask the address with the given prefix length.
        +
        Parameters:
        prefixLength - prefix length
        +
        Returns:
        an address of which the last 128 - prefixLength bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithPrefixLength

        +
        public IPv6Address maximumAddressWithPrefixLength(int prefixLength)
        +
        Calculate the maximum address with the given prefix length.
        +
        Parameters:
        prefixLength - prefix length
        +
        Returns:
        an address of which the last 128 - prefixLength bits are one
        +
      • +
      + + + + + + + +
        +
      • +

        toShortArray

        +
        public short[] toShortArray()
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..5f823eb --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (IPv6 0.2 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..6aceea8 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html @@ -0,0 +1,405 @@ + + + + + + +IPv6AddressPool (IPv6 0.2 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressPool

        +
        public IPv6AddressPool(IPv6Address first,
        +               IPv6Address last,
        +               int prefixLength)
        +
        Create a pool in between the given first and last address (inclusive) which is completely free. The given prefix length is the prefix + length used for allocating subnets from this range. The whole range should be "aligned" on a multiple of subnets of this prefix + length (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given prefix + length).
        +
        Parameters:
        first - first ip address of the range
        last - last ip address of the range
        prefixLength - prefix length with which to allocate subnets from this range
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..085b6ed --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html @@ -0,0 +1,466 @@ + + + + + + +IPv6AddressRange (IPv6 0.2 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + + + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6Network.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6Network.html new file mode 100644 index 0000000..1652398 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6Network.html @@ -0,0 +1,370 @@ + + + + + + +IPv6Network (IPv6 0.2 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6Network

        +
        public IPv6Network(IPv6Address address,
        +           int prefixLength)
        +
        Construct from address and prefix length.
        +
        Parameters:
        address - address
        prefixLength - prefix length, in range ]0, 128]
        +
      • +
      + + + +
        +
      • +

        IPv6Network

        +
        public IPv6Network(IPv6Address first,
        +           IPv6Address last)
        +
        Construct from first and last address. This will construct the smallest possible network ("longest prefix length") which contains + both addresses.
        +
        Parameters:
        first - first address
        last - last address
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        getPrefixLength

        +
        public int getPrefixLength()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..985ec0b --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (IPv6 0.2 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..b730db2 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html @@ -0,0 +1,265 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6Address (IPv6 0.2 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..387cd6a --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressHelpers (IPv6 0.2 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressHelpers

+
+
No usage of be.jvb.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..8e0d963 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,154 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressPool (IPv6 0.2 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..2b78100 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,207 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressRange (IPv6 0.2 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..a994d10 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html @@ -0,0 +1,173 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6Network (IPv6 0.2 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..354895f --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6NetworkHelpers (IPv6 0.2 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6NetworkHelpers

+
+
No usage of be.jvb.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-frame.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-frame.html new file mode 100644 index 0000000..acbdb83 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-frame.html @@ -0,0 +1,25 @@ + + + + + + +be.jvb.ipv6 (IPv6 0.2 API) + + + + +

be.jvb.ipv6

+ + + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-summary.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-summary.html new file mode 100644 index 0000000..e754032 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-summary.html @@ -0,0 +1,165 @@ + + + + + + +be.jvb.ipv6 (IPv6 0.2 API) + + + + + + + + + + +
+

Package be.jvb.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    +
  • +
+
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-tree.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-tree.html new file mode 100644 index 0000000..e541f40 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-tree.html @@ -0,0 +1,132 @@ + + + + + + +be.jvb.ipv6 Class Hierarchy (IPv6 0.2 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package be.jvb.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-use.html b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-use.html new file mode 100644 index 0000000..a3887ad --- /dev/null +++ b/artifacts/0.2/doc/apidocs/be/jvb/ipv6/package-use.html @@ -0,0 +1,150 @@ + + + + + + +Uses of Package be.jvb.ipv6 (IPv6 0.2 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
be.jvb.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + +
    Classes in be.jvb.ipv6 used by be.jvb.ipv6 
    Class and Description
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    +
  • +
+
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/constant-values.html b/artifacts/0.2/doc/apidocs/constant-values.html new file mode 100644 index 0000000..111ce93 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (IPv6 0.2 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/deprecated-list.html b/artifacts/0.2/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..7e4997d --- /dev/null +++ b/artifacts/0.2/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (IPv6 0.2 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/help-doc.html b/artifacts/0.2/doc/apidocs/help-doc.html new file mode 100644 index 0000000..b4d69f8 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (IPv6 0.2 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/index-all.html b/artifacts/0.2/doc/apidocs/index-all.html new file mode 100644 index 0000000..42cef12 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/index-all.html @@ -0,0 +1,354 @@ + + + + + + +Index (IPv6 0.2 API) + + + + + + + +
+ + + + + +
+ + +
A B C D E F G H I M O R S T  + + +

A

+
+
add(long) - Method in class be.jvb.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
+ + + +

B

+
+
be.jvb.ipv6 - package be.jvb.ipv6
+
 
+
+ + + +

C

+
+
compareTo(IPv6Address) - Method in class be.jvb.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
contains(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class be.jvb.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6Network
+
 
+
extend(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
fromInetAddress(InetAddress) - Static method in class be.jvb.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromString(String) - Static method in class be.jvb.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class be.jvb.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
getLast() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
getLowBits() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
getPrefixLength() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
+ + + +

I

+
+
IPv6Address - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in be.jvb.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressPool(IPv6Address, IPv6Address, int) - Constructor for class be.jvb.ipv6.IPv6AddressPool
+
+
Create a pool in between the given first and last address (inclusive) which is completely free.
+
+
IPv6AddressRange - Class in be.jvb.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6AddressRange(IPv6Address, IPv6Address) - Constructor for class be.jvb.ipv6.IPv6AddressRange
+
 
+
IPv6Network - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6Network(IPv6Address, int) - Constructor for class be.jvb.ipv6.IPv6Network
+
+
Construct from address and prefix length.
+
+
IPv6Network(IPv6Address, IPv6Address) - Constructor for class be.jvb.ipv6.IPv6Network
+
+
Construct from first and last address.
+
+
IPv6NetworkHelpers - Class in be.jvb.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class be.jvb.ipv6.IPv6NetworkHelpers
+
 
+
isExhausted() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
iterator() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
+ + + +

M

+
+
maskWithPrefixLength(int) - Method in class be.jvb.ipv6.IPv6Address
+
+
Mask the address with the given prefix length.
+
+
maximumAddressWithPrefixLength(int) - Method in class be.jvb.ipv6.IPv6Address
+
+
Calculate the maximum address with the given prefix length.
+
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
subtract(long) - Method in class be.jvb.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toInetAddress() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toShortArray() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
+A B C D E F G H I M O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/index.html b/artifacts/0.2/doc/apidocs/index.html new file mode 100644 index 0000000..9f9d206 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +IPv6 0.2 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="be/jvb/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.2/doc/apidocs/overview-tree.html b/artifacts/0.2/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..09d25ff --- /dev/null +++ b/artifacts/0.2/doc/apidocs/overview-tree.html @@ -0,0 +1,136 @@ + + + + + + +Class Hierarchy (IPv6 0.2 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.2/doc/apidocs/package-list b/artifacts/0.2/doc/apidocs/package-list new file mode 100644 index 0000000..d2a5ec8 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/package-list @@ -0,0 +1 @@ +be.jvb.ipv6 diff --git a/artifacts/0.2/doc/apidocs/resources/background.gif b/artifacts/0.2/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.2/doc/apidocs/stylesheet.css b/artifacts/0.2/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.2/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.3/doc/apidocs/allclasses-frame.html b/artifacts/0.3/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..d58bdf9 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/allclasses-frame.html @@ -0,0 +1,24 @@ + + + + + + +All Classes (IPv6 0.3 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.3/doc/apidocs/allclasses-noframe.html b/artifacts/0.3/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..e7f6f0d --- /dev/null +++ b/artifacts/0.3/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,24 @@ + + + + + + +All Classes (IPv6 0.3 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6Address.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6Address.html new file mode 100644 index 0000000..18a431d --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6Address.html @@ -0,0 +1,449 @@ + + + + + + +IPv6Address (IPv6 0.3 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithPrefixLength

        +
        public IPv6Address maskWithPrefixLength(int prefixLength)
        +
        Mask the address with the given prefix length.
        +
        Parameters:
        prefixLength - prefix length
        +
        Returns:
        an address of which the last 128 - prefixLength bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithPrefixLength

        +
        public IPv6Address maximumAddressWithPrefixLength(int prefixLength)
        +
        Calculate the maximum address with the given prefix length.
        +
        Parameters:
        prefixLength - prefix length
        +
        Returns:
        an address of which the last 128 - prefixLength bits are one
        +
      • +
      + + + + + + + +
        +
      • +

        toShortArray

        +
        public short[] toShortArray()
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..7075a58 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (IPv6 0.3 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..523b3ce --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html @@ -0,0 +1,484 @@ + + + + + + +IPv6AddressPool (IPv6 0.3 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressPool

        +
        public IPv6AddressPool(IPv6Address first,
        +               IPv6Address last,
        +               int prefixLength)
        +
        Create a pool in between the given first and last address (inclusive) which is completely free. The given prefix length is the prefix + length used for allocating subnets from this range. The whole range should be "aligned" on a multiple of subnets of this prefix + length (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given prefix + length).
        +
        Parameters:
        first - first ip address of the range
        last - last ip address of the range
        prefixLength - prefix length with which to allocate subnets from this range
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..d394199 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html @@ -0,0 +1,466 @@ + + + + + + +IPv6AddressRange (IPv6 0.3 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + + + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6Network.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6Network.html new file mode 100644 index 0000000..63d1b3a --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6Network.html @@ -0,0 +1,370 @@ + + + + + + +IPv6Network (IPv6 0.3 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6Network

        +
        public IPv6Network(IPv6Address address,
        +           int prefixLength)
        +
        Construct from address and prefix length.
        +
        Parameters:
        address - address
        prefixLength - prefix length, in range ]0, 128]
        +
      • +
      + + + +
        +
      • +

        IPv6Network

        +
        public IPv6Network(IPv6Address first,
        +           IPv6Address last)
        +
        Construct from first and last address. This will construct the smallest possible network ("longest prefix length") which contains + both addresses.
        +
        Parameters:
        first - first address
        last - last address
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        getPrefixLength

        +
        public int getPrefixLength()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..de943ca --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (IPv6 0.3 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..d30a11e --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html @@ -0,0 +1,265 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6Address (IPv6 0.3 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..a8658a9 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressHelpers (IPv6 0.3 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressHelpers

+
+
No usage of be.jvb.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..fb58c7f --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,154 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressPool (IPv6 0.3 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..1fa96cb --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,207 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressRange (IPv6 0.3 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..4c4b234 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html @@ -0,0 +1,190 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6Network (IPv6 0.3 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..baa3f79 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6NetworkHelpers (IPv6 0.3 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6NetworkHelpers

+
+
No usage of be.jvb.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-frame.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-frame.html new file mode 100644 index 0000000..bc02d92 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-frame.html @@ -0,0 +1,25 @@ + + + + + + +be.jvb.ipv6 (IPv6 0.3 API) + + + + +

be.jvb.ipv6

+ + + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-summary.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-summary.html new file mode 100644 index 0000000..8c9b748 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-summary.html @@ -0,0 +1,165 @@ + + + + + + +be.jvb.ipv6 (IPv6 0.3 API) + + + + + + + + + + +
+

Package be.jvb.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    +
  • +
+
+ + + + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-tree.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-tree.html new file mode 100644 index 0000000..4e1e8be --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-tree.html @@ -0,0 +1,132 @@ + + + + + + +be.jvb.ipv6 Class Hierarchy (IPv6 0.3 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package be.jvb.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-use.html b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-use.html new file mode 100644 index 0000000..d5d64d1 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/be/jvb/ipv6/package-use.html @@ -0,0 +1,150 @@ + + + + + + +Uses of Package be.jvb.ipv6 (IPv6 0.3 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
be.jvb.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + +
    Classes in be.jvb.ipv6 used by be.jvb.ipv6 
    Class and Description
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    +
  • +
+
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/constant-values.html b/artifacts/0.3/doc/apidocs/constant-values.html new file mode 100644 index 0000000..81ab14f --- /dev/null +++ b/artifacts/0.3/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (IPv6 0.3 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/deprecated-list.html b/artifacts/0.3/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..08d2be0 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (IPv6 0.3 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/help-doc.html b/artifacts/0.3/doc/apidocs/help-doc.html new file mode 100644 index 0000000..0b20fce --- /dev/null +++ b/artifacts/0.3/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (IPv6 0.3 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/index-all.html b/artifacts/0.3/doc/apidocs/index-all.html new file mode 100644 index 0000000..f8ff12f --- /dev/null +++ b/artifacts/0.3/doc/apidocs/index-all.html @@ -0,0 +1,364 @@ + + + + + + +Index (IPv6 0.3 API) + + + + + + + +
+ + + + + +
+ + +
A B C D E F G H I M O R S T  + + +

A

+
+
add(int) - Method in class be.jvb.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
+ + + +

B

+
+
be.jvb.ipv6 - package be.jvb.ipv6
+
 
+
+ + + +

C

+
+
compareTo(IPv6Address) - Method in class be.jvb.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
contains(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class be.jvb.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6Network
+
 
+
extend(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
fromInetAddress(InetAddress) - Static method in class be.jvb.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromString(String) - Static method in class be.jvb.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class be.jvb.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
getLast() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
getPrefixLength() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
+ + + +

I

+
+
IPv6Address - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in be.jvb.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressPool(IPv6Address, IPv6Address, int) - Constructor for class be.jvb.ipv6.IPv6AddressPool
+
+
Create a pool in between the given first and last address (inclusive) which is completely free.
+
+
IPv6AddressRange - Class in be.jvb.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6AddressRange(IPv6Address, IPv6Address) - Constructor for class be.jvb.ipv6.IPv6AddressRange
+
 
+
IPv6Network - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6Network(IPv6Address, int) - Constructor for class be.jvb.ipv6.IPv6Network
+
+
Construct from address and prefix length.
+
+
IPv6Network(IPv6Address, IPv6Address) - Constructor for class be.jvb.ipv6.IPv6Network
+
+
Construct from first and last address.
+
+
IPv6NetworkHelpers - Class in be.jvb.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class be.jvb.ipv6.IPv6NetworkHelpers
+
 
+
isExhausted() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
iterator() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
+ + + +

M

+
+
maskWithPrefixLength(int) - Method in class be.jvb.ipv6.IPv6Address
+
+
Mask the address with the given prefix length.
+
+
maximumAddressWithPrefixLength(int) - Method in class be.jvb.ipv6.IPv6Address
+
+
Calculate the maximum address with the given prefix length.
+
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
subtract(int) - Method in class be.jvb.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toInetAddress() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toShortArray() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
+A B C D E F G H I M O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/index.html b/artifacts/0.3/doc/apidocs/index.html new file mode 100644 index 0000000..57c5951 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +IPv6 0.3 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="be/jvb/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.3/doc/apidocs/overview-tree.html b/artifacts/0.3/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..78247bf --- /dev/null +++ b/artifacts/0.3/doc/apidocs/overview-tree.html @@ -0,0 +1,136 @@ + + + + + + +Class Hierarchy (IPv6 0.3 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2011. All Rights Reserved.

+ + diff --git a/artifacts/0.3/doc/apidocs/package-list b/artifacts/0.3/doc/apidocs/package-list new file mode 100644 index 0000000..d2a5ec8 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/package-list @@ -0,0 +1 @@ +be.jvb.ipv6 diff --git a/artifacts/0.3/doc/apidocs/resources/background.gif b/artifacts/0.3/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.3/doc/apidocs/stylesheet.css b/artifacts/0.3/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.3/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.4/doc/apidocs/allclasses-frame.html b/artifacts/0.4/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..ae21246 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (IPv6 0.4 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.4/doc/apidocs/allclasses-noframe.html b/artifacts/0.4/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..48665e5 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (IPv6 0.4 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6Address.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6Address.html new file mode 100644 index 0000000..1f47c0a --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6Address.html @@ -0,0 +1,537 @@ + + + + + + +IPv6Address (IPv6 0.4 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6Address

        +
        public IPv6Address(long highBits,
        +           long lowBits)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        +
        Overrides:
        +
        toString in class Object
        +
        Returns:
        String representation of the IPv6 Address, using shorthand notation whenever possible.
        +
      • +
      + + + +
        +
      • +

        toShortArray

        +
        public short[] toShortArray()
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..4dd2a75 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (IPv6 0.4 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..4ac161d --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressPool.html @@ -0,0 +1,484 @@ + + + + + + +IPv6AddressPool (IPv6 0.4 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressPool

        +
        public IPv6AddressPool(IPv6Address first,
        +               IPv6Address last,
        +               int prefixLength)
        +
        Create a pool in between the given first and last address (inclusive) which is completely free. The given prefix length is the prefix + length used for allocating subnets from this range. The whole range should be "aligned" on a multiple of subnets of this prefix + length (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given prefix + length).
        +
        Parameters:
        first - first ip address of the range
        last - last ip address of the range
        prefixLength - prefix length with which to allocate subnets from this range
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..7abac37 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6AddressRange.html @@ -0,0 +1,466 @@ + + + + + + +IPv6AddressRange (IPv6 0.4 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + + + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6Network.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6Network.html new file mode 100644 index 0000000..d825f37 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6Network.html @@ -0,0 +1,401 @@ + + + + + + +IPv6Network (IPv6 0.4 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6Network

        +
        public IPv6Network(IPv6Address address,
        +           IPv6NetworkMask networkMask)
        +
        Construct from address and network mask.
        +
        Parameters:
        address - address
        networkMask - network mask
        +
      • +
      + + + +
        +
      • +

        IPv6Network

        +
        public IPv6Network(IPv6Address address,
        +           int prefixLength)
        +
        Construct from address and prefix length.
        +
        Parameters:
        address - address
        prefixLength - prefix length
        +
      • +
      + + + +
        +
      • +

        IPv6Network

        +
        public IPv6Network(IPv6Address first,
        +           IPv6Address last)
        +
        Construct from first and last address. This will construct the smallest possible network ("longest prefix length") which contains + both addresses.
        +
        Parameters:
        first - first address
        last - last address
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        getPrefixLength

        +
        public int getPrefixLength()
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..570fcbd --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (IPv6 0.4 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6NetworkMask.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..052aa98 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/IPv6NetworkMask.html @@ -0,0 +1,348 @@ + + + + + + +IPv6NetworkMask (IPv6 0.4 API) + + + + + + + + + + + +
+
be.jvb.ipv6
+

Class IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkMask

        +
        public IPv6NetworkMask(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        Parameters:
        iPv6Address - address to use as network mask
        +
        Throws:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        IPv6NetworkMask

        +
        public IPv6NetworkMask(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        Parameters:
        prefixLength - prefix length
        +
        Throws:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      +
    • +
    + + +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..a0e4f0c --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6Address.html @@ -0,0 +1,280 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6Address (IPv6 0.4 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..0334d5c --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressHelpers (IPv6 0.4 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressHelpers

+
+
No usage of be.jvb.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..e1ce2af --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,154 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressPool (IPv6 0.4 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..3af3d0c --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,207 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6AddressRange (IPv6 0.4 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..2d8046c --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6Network.html @@ -0,0 +1,190 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6Network (IPv6 0.4 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..df87f99 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6NetworkHelpers (IPv6 0.4 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6NetworkHelpers

+
+
No usage of be.jvb.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..400a695 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,175 @@ + + + + + + +Uses of Class be.jvb.ipv6.IPv6NetworkMask (IPv6 0.4 API) + + + + + + + + + + +
+

Uses of Class
be.jvb.ipv6.IPv6NetworkMask

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-frame.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-frame.html new file mode 100644 index 0000000..4197441 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +be.jvb.ipv6 (IPv6 0.4 API) + + + + +

be.jvb.ipv6

+ + + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-summary.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-summary.html new file mode 100644 index 0000000..4e55ce6 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +be.jvb.ipv6 (IPv6 0.4 API) + + + + + + + + + + +
+

Package be.jvb.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-tree.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-tree.html new file mode 100644 index 0000000..292cad4 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +be.jvb.ipv6 Class Hierarchy (IPv6 0.4 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package be.jvb.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-use.html b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-use.html new file mode 100644 index 0000000..3a45787 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/be/jvb/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +Uses of Package be.jvb.ipv6 (IPv6 0.4 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
be.jvb.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + +
    Classes in be.jvb.ipv6 used by be.jvb.ipv6 
    Class and Description
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/constant-values.html b/artifacts/0.4/doc/apidocs/constant-values.html new file mode 100644 index 0000000..0359573 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (IPv6 0.4 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/deprecated-list.html b/artifacts/0.4/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..88b4454 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (IPv6 0.4 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/help-doc.html b/artifacts/0.4/doc/apidocs/help-doc.html new file mode 100644 index 0000000..e8699d2 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (IPv6 0.4 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/index-all.html b/artifacts/0.4/doc/apidocs/index-all.html new file mode 100644 index 0000000..50e9f33 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/index-all.html @@ -0,0 +1,408 @@ + + + + + + +Index (IPv6 0.4 API) + + + + + + + +
+ + + + + +
+ + +
A B C D E F G H I M N O R S T  + + +

A

+
+
add(int) - Method in class be.jvb.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - Method in class be.jvb.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - Method in class be.jvb.ipv6.IPv6NetworkMask
+
 
+
+ + + +

B

+
+
be.jvb.ipv6 - package be.jvb.ipv6
+
 
+
+ + + +

C

+
+
compareTo(IPv6Address) - Method in class be.jvb.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
contains(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class be.jvb.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6Network
+
 
+
equals(Object) - Method in class be.jvb.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
fromInetAddress(InetAddress) - Static method in class be.jvb.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromString(String) - Static method in class be.jvb.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class be.jvb.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
getLast() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
getNetmask() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
getPrefixLength() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
hashCode() - Method in class be.jvb.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6Address(long, long) - Constructor for class be.jvb.ipv6.IPv6Address
+
 
+
IPv6AddressHelpers - Class in be.jvb.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class be.jvb.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressPool(IPv6Address, IPv6Address, int) - Constructor for class be.jvb.ipv6.IPv6AddressPool
+
+
Create a pool in between the given first and last address (inclusive) which is completely free.
+
+
IPv6AddressRange - Class in be.jvb.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6AddressRange(IPv6Address, IPv6Address) - Constructor for class be.jvb.ipv6.IPv6AddressRange
+
 
+
IPv6Network - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6Network(IPv6Address, IPv6NetworkMask) - Constructor for class be.jvb.ipv6.IPv6Network
+
+
Construct from address and network mask.
+
+
IPv6Network(IPv6Address, int) - Constructor for class be.jvb.ipv6.IPv6Network
+
+
Construct from address and prefix length.
+
+
IPv6Network(IPv6Address, IPv6Address) - Constructor for class be.jvb.ipv6.IPv6Network
+
+
Construct from first and last address.
+
+
IPv6NetworkHelpers - Class in be.jvb.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class be.jvb.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - Class in be.jvb.ipv6
+
+
Immutable representation of an IPv6 network mask.
+
+
IPv6NetworkMask(IPv6Address) - Constructor for class be.jvb.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
IPv6NetworkMask(int) - Constructor for class be.jvb.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
isExhausted() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
iterator() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - Method in class be.jvb.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - Method in class be.jvb.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
+ + + +

N

+
+
numberOfLeadingOnes() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class be.jvb.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
subtract(int) - Method in class be.jvb.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toInetAddress() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toShortArray() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6Address
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6Network
+
 
+
toString() - Method in class be.jvb.ipv6.IPv6NetworkMask
+
 
+
+A B C D E F G H I M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/index.html b/artifacts/0.4/doc/apidocs/index.html new file mode 100644 index 0000000..247989f --- /dev/null +++ b/artifacts/0.4/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +IPv6 0.4 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="be/jvb/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.4/doc/apidocs/overview-tree.html b/artifacts/0.4/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..9fea035 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +Class Hierarchy (IPv6 0.4 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.4/doc/apidocs/package-list b/artifacts/0.4/doc/apidocs/package-list new file mode 100644 index 0000000..d2a5ec8 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/package-list @@ -0,0 +1 @@ +be.jvb.ipv6 diff --git a/artifacts/0.4/doc/apidocs/resources/background.gif b/artifacts/0.4/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.4/doc/apidocs/stylesheet.css b/artifacts/0.4/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.4/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.5/doc/apidocs/allclasses-frame.html b/artifacts/0.5/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..7d45931 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.5 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.5/doc/apidocs/allclasses-noframe.html b/artifacts/0.5/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..03fb674 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.5 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..14deeb8 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,551 @@ + + + + + + +IPv6Address (Java IPv6 Library 0.5 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6Address

        +
        public IPv6Address(long highBits,
        +           long lowBits)
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        +
        Overrides:
        +
        toString in class Object
        +
        Returns:
        String representation of the IPv6 address, using shorthand notation whenever possible.
        +
      • +
      + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        String representation of the IPv6 address, never using shorthand notation.
        +
      • +
      + + + +
        +
      • +

        toShortArray

        +
        public short[] toShortArray()
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..80fb952 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.5 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..18ba263 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,498 @@ + + + + + + +IPv6AddressPool (Java IPv6 Library 0.5 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressPool

        +
        public IPv6AddressPool(IPv6Address first,
        +               IPv6Address last,
        +               IPv6NetworkMask allocationSubnetSize)
        +
        Create a pool in between the given first and last address (inclusive) which is completely free. The given subnet size is the network + mask (thus size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of + this size (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet + size).
        +
        Parameters:
        first - first ip address of the range
        last - last ip address of the range
        allocationSubnetSize - size of the subnets that will be allocated
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..f9b3949 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,480 @@ + + + + + + +IPv6AddressRange (Java IPv6 Library 0.5 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + + + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..3218481 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,405 @@ + + + + + + +IPv6Network (Java IPv6 Library 0.5 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6Network

        +
        public IPv6Network(IPv6Address address,
        +           IPv6NetworkMask networkMask)
        +
        Construct from address and network mask.
        +
        Parameters:
        address - address
        networkMask - network mask
        +
      • +
      + + + +
        +
      • +

        IPv6Network

        +
        public IPv6Network(IPv6Address address,
        +           int prefixLength)
        +
        Construct from address and prefix length.
        +
        Parameters:
        address - address
        prefixLength - prefix length
        +
      • +
      + + + +
        +
      • +

        IPv6Network

        +
        public IPv6Network(IPv6Address first,
        +           IPv6Address last)
        +
        Construct from first and last address. This will construct the smallest possible network ("longest prefix length") which contains + both addresses.
        +
        Parameters:
        first - first address
        last - last address
        +
      • +
      +
    • +
    + + +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..e99ecad --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.5 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..796b601 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,348 @@ + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.5 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkMask

        +
        public IPv6NetworkMask(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        Parameters:
        iPv6Address - address to use as network mask
        +
        Throws:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        IPv6NetworkMask

        +
        public IPv6NetworkMask(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        Parameters:
        prefixLength - prefix length
        +
        Throws:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      +
    • +
    + + +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..21a1acf --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,280 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.5 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..b50de40 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.5 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+
No usage of com.googlecode.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..24aaf12 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,154 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.5 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..4d3c0e7 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,207 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.5 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..6247329 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,190 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.5 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..fad4dd5 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.5 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+
No usage of com.googlecode.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..6ee780e --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,182 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.5 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..ea4b338 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.5 API) + + + + +

com.googlecode.ipv6

+ + + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..6928914 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.5 API) + + + + + + + + + + +
+

Package com.googlecode.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..079567a --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.5 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package com.googlecode.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..52933ba --- /dev/null +++ b/artifacts/0.5/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.5 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
com.googlecode.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/constant-values.html b/artifacts/0.5/doc/apidocs/constant-values.html new file mode 100644 index 0000000..e14983e --- /dev/null +++ b/artifacts/0.5/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (Java IPv6 Library 0.5 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/deprecated-list.html b/artifacts/0.5/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..780b7a6 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (Java IPv6 Library 0.5 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/help-doc.html b/artifacts/0.5/doc/apidocs/help-doc.html new file mode 100644 index 0000000..217e124 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (Java IPv6 Library 0.5 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/index-all.html b/artifacts/0.5/doc/apidocs/index-all.html new file mode 100644 index 0000000..1e8ae8e --- /dev/null +++ b/artifacts/0.5/doc/apidocs/index-all.html @@ -0,0 +1,408 @@ + + + + + + +Index (Java IPv6 Library 0.5 API) + + + + + + + +
+ + + + + +
+ + +
A C D E F G H I M N O R S T  + + +

A

+
+
add(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
+
 
+
compareTo(IPv6Address) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
fromInetAddress(InetAddress) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getNetmask() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6Address(long, long) - Constructor for class com.googlecode.ipv6.IPv6Address
+
 
+
IPv6AddressHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressPool(IPv6Address, IPv6Address, IPv6NetworkMask) - Constructor for class com.googlecode.ipv6.IPv6AddressPool
+
+
Create a pool in between the given first and last address (inclusive) which is completely free.
+
+
IPv6AddressRange - Class in com.googlecode.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6AddressRange(IPv6Address, IPv6Address) - Constructor for class com.googlecode.ipv6.IPv6AddressRange
+
 
+
IPv6Network - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6Network(IPv6Address, IPv6NetworkMask) - Constructor for class com.googlecode.ipv6.IPv6Network
+
+
Construct from address and network mask.
+
+
IPv6Network(IPv6Address, int) - Constructor for class com.googlecode.ipv6.IPv6Network
+
+
Construct from address and prefix length.
+
+
IPv6Network(IPv6Address, IPv6Address) - Constructor for class com.googlecode.ipv6.IPv6Network
+
+
Construct from first and last address.
+
+
IPv6NetworkHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network mask.
+
+
IPv6NetworkMask(IPv6Address) - Constructor for class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
IPv6NetworkMask(int) - Constructor for class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
isExhausted() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
iterator() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
+ + + +

N

+
+
numberOfLeadingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
subtract(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toInetAddress() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toShortArray() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+A C D E F G H I M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/index.html b/artifacts/0.5/doc/apidocs/index.html new file mode 100644 index 0000000..9daa62e --- /dev/null +++ b/artifacts/0.5/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +Java IPv6 Library 0.5 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="com/googlecode/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.5/doc/apidocs/overview-tree.html b/artifacts/0.5/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..7c8aada --- /dev/null +++ b/artifacts/0.5/doc/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +Class Hierarchy (Java IPv6 Library 0.5 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.5/doc/apidocs/package-list b/artifacts/0.5/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.5/doc/apidocs/resources/background.gif b/artifacts/0.5/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.5/doc/apidocs/stylesheet.css b/artifacts/0.5/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.5/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.6/doc/apidocs/allclasses-frame.html b/artifacts/0.6/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..1cbbd8d --- /dev/null +++ b/artifacts/0.6/doc/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.6 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.6/doc/apidocs/allclasses-noframe.html b/artifacts/0.6/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..8914387 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.6 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..7d185f3 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,515 @@ + + + + + + +IPv6Address (Java IPv6 Library 0.6 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        +
        Overrides:
        +
        toString in class Object
        +
        Returns:
        String representation of the IPv6 address, using shorthand notation whenever possible.
        +
      • +
      + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        String representation of the IPv6 address, never using shorthand notation.
        +
      • +
      + + + +
        +
      • +

        toShortArray

        +
        public short[] toShortArray()
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..851341f --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.6 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..fce0d1a --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,474 @@ + + + + + + +IPv6AddressPool (Java IPv6 Library 0.6 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromRangeAndSubnet

        +
        public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
        +                                 IPv6NetworkMask allocationSubnetSize)
        +
        Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size).
        +
        Parameters:
        range - range from within to allocate
        allocationSubnetSize - size of the subnets that will be allocated
        +
      • +
      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..826aec8 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,459 @@ + + + + + + +IPv6AddressRange (Java IPv6 Library 0.6 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..0d7c491 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,368 @@ + + + + + + +IPv6Network (Java IPv6 Library 0.6 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddressAndMask

        +
        public static IPv6Network fromAddressAndMask(IPv6Address address,
        +                             IPv6NetworkMask networkMask)
        +
        Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
        +
        Parameters:
        address - IPv6 address (the network address or any other address within the network)
        networkMask - IPv6 network mask
        +
        Returns:
        IPv6 network
        +
      • +
      + + + +
        +
      • +

        fromTwoAddresses

        +
        public static IPv6Network fromTwoAddresses(IPv6Address one,
        +                           IPv6Address two)
        +
        Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses.
        +
        Parameters:
        one - address one
        two - address two, should be bigger than address one
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 network
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        +
        Overrides:
        +
        toLongString in class IPv6AddressRange
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..b99359d --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.6 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..bf372ec --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,328 @@ + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.6 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddress

        +
        public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        Parameters:
        iPv6Address - address to use as network mask
        +
        Throws:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        fromPrefixLength

        +
        public static IPv6NetworkMask fromPrefixLength(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        Parameters:
        prefixLength - prefix length
        +
        Throws:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      + + + +
        +
      • +

        asPrefixLength

        +
        public int asPrefixLength()
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..bade683 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,263 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.6 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..5b79b2c --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.6 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+
No usage of com.googlecode.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..ed3f1d9 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,161 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.6 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..34e6913 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,219 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.6 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..8672cb2 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,204 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.6 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..3ef3831 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.6 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+
No usage of com.googlecode.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..ed72cb2 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,187 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.6 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+
+ +
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..17e8685 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.6 API) + + + + +

com.googlecode.ipv6

+ + + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..ddea75a --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.6 API) + + + + + + + + + + +
+

Package com.googlecode.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..ac0279f --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.6 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package com.googlecode.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..919bf6d --- /dev/null +++ b/artifacts/0.6/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.6 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
com.googlecode.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/constant-values.html b/artifacts/0.6/doc/apidocs/constant-values.html new file mode 100644 index 0000000..ad35cab --- /dev/null +++ b/artifacts/0.6/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (Java IPv6 Library 0.6 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/deprecated-list.html b/artifacts/0.6/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..3e09c9c --- /dev/null +++ b/artifacts/0.6/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (Java IPv6 Library 0.6 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/help-doc.html b/artifacts/0.6/doc/apidocs/help-doc.html new file mode 100644 index 0000000..4e0f949 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (Java IPv6 Library 0.6 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/index-all.html b/artifacts/0.6/doc/apidocs/index-all.html new file mode 100644 index 0000000..de91d8b --- /dev/null +++ b/artifacts/0.6/doc/apidocs/index-all.html @@ -0,0 +1,402 @@ + + + + + + +Index (Java IPv6 Library 0.6 API) + + + + + + + +
+ + + + + +
+ + +
A C D E F G H I M N O R S T  + + +

A

+
+
add(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
+
 
+
compareTo(IPv6Address) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
fromAddress(IPv6Address) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+
+
fromFirstAndLast(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
fromInetAddress(InetAddress) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromPrefixLength(int) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Create a pool of the given range (boundaries inclusive) which is completely free.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
fromTwoAddresses(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from the two addresses within the network.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getNetmask() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressRange - Class in com.googlecode.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6Network - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6NetworkHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network mask.
+
+
isExhausted() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
iterator() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
+ + + +

N

+
+
numberOfLeadingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
subtract(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toInetAddress() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toShortArray() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+A C D E F G H I M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/index.html b/artifacts/0.6/doc/apidocs/index.html new file mode 100644 index 0000000..fd18c47 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +Java IPv6 Library 0.6 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="com/googlecode/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.6/doc/apidocs/overview-tree.html b/artifacts/0.6/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..fea0a86 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +Class Hierarchy (Java IPv6 Library 0.6 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2012. All Rights Reserved.

+ + diff --git a/artifacts/0.6/doc/apidocs/package-list b/artifacts/0.6/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.6/doc/apidocs/resources/background.gif b/artifacts/0.6/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 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 YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.6/doc/apidocs/stylesheet.css b/artifacts/0.6/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.6/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/artifacts/0.7/doc/apidocs/allclasses-frame.html b/artifacts/0.7/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..35bc129 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/allclasses-frame.html @@ -0,0 +1,46 @@ + + + + + + + +All Classes (Java IPv6 Library 0.7 API) + + + + + + + + + + + +All Classes +
+ + + + + +
BitSetHelpers +
+IPv6Address +
+IPv6AddressHelpers +
+IPv6AddressPool +
+IPv6AddressRange +
+IPv6Network +
+IPv6NetworkHelpers +
+IPv6NetworkMask +
+
+ + + diff --git a/artifacts/0.7/doc/apidocs/allclasses-noframe.html b/artifacts/0.7/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..2b4a7fa --- /dev/null +++ b/artifacts/0.7/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,46 @@ + + + + + + + +All Classes (Java IPv6 Library 0.7 API) + + + + + + + + + + + +All Classes +
+ + + + + +
BitSetHelpers +
+IPv6Address +
+IPv6AddressHelpers +
+IPv6AddressPool +
+IPv6AddressRange +
+IPv6Network +
+IPv6NetworkHelpers +
+IPv6NetworkMask +
+
+ + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/BitSetHelpers.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/BitSetHelpers.html new file mode 100644 index 0000000..8952964 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/BitSetHelpers.html @@ -0,0 +1,232 @@ + + + + + + + +BitSetHelpers (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class BitSetHelpers

+
+java.lang.Object
+  extended by com.googlecode.ipv6.BitSetHelpers
+
+
+
+
public class BitSetHelpers
extends Object
+ + +

+This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + method. However, for java-6 compatibility, we go this way. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
BitSetHelpers() + +
+           
+  + + + + + + + +
+Method Summary
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+BitSetHelpers

+
+public BitSetHelpers()
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..0e542c4 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,652 @@ + + + + + + + +IPv6Address (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6Address

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6Address
+
+
+
All Implemented Interfaces:
Comparable<IPv6Address>
+
+
+
+
public final class IPv6Address
extends Object
implements Comparable<IPv6Address>
+ + +

+Immutable representation of an IPv6 address. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ IPv6Addressadd(int value) + +
+          Addition.
+ intcompareTo(IPv6Address that) + +
+           
+ booleanequals(Object o) + +
+           
+static IPv6AddressfromInetAddress(InetAddress inetAddress) + +
+          Create an IPv6 address from a java.net.Inet6Address.
+static IPv6AddressfromString(String string) + +
+          Create an IPv6 address from its String representation.
+ longgetHighBits() + +
+           
+ longgetLowBits() + +
+           
+ inthashCode() + +
+           
+ IPv6AddressmaskWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Mask the address with the given network mask.
+ IPv6AddressmaximumAddressWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Calculate the maximum address with the given network mask.
+ intnumberOfLeadingOnes() + +
+           
+ intnumberOfLeadingZeroes() + +
+           
+ intnumberOfTrailingOnes() + +
+           
+ intnumberOfTrailingZeroes() + +
+           
+ IPv6Addresssubtract(int value) + +
+          Subtraction.
+ InetAddresstoInetAddress() + +
+           
+ StringtoLongString() + +
+           
+ short[]toShortArray() + +
+           
+ StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+fromString

+
+public static IPv6Address fromString(String string)
+
+
Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::". +

+

+
+
+
+
Parameters:
string - string representation +
Returns:
IPv6 address
+
+
+
+ +

+fromInetAddress

+
+public static IPv6Address fromInetAddress(InetAddress inetAddress)
+
+
Create an IPv6 address from a java.net.Inet6Address. +

+

+
+
+
+
Parameters:
inetAddress - Inet6Address representation +
Returns:
IPv6 address
+
+
+
+ +

+toInetAddress

+
+public InetAddress toInetAddress()
+                          throws UnknownHostException
+
+
+
+
+
+ +
Throws: +
UnknownHostException
+
+
+
+ +

+add

+
+public IPv6Address add(int value)
+
+
Addition. Will never overflow, but wraps around when the highest ip address has been reached. +

+

+
+
+
+
Parameters:
value - value to add +
Returns:
new IPv6 address
+
+
+
+ +

+subtract

+
+public IPv6Address subtract(int value)
+
+
Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. +

+

+
+
+
+
Parameters:
value - value to substract +
Returns:
new IPv6 address
+
+
+
+ +

+maskWithNetworkMask

+
+public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
+
+
Mask the address with the given network mask. +

+

+
+
+
+
Parameters:
networkMask - network mask +
Returns:
an address of which the last 128 - networkMask.asPrefixLength() bits are zero
+
+
+
+ +

+maximumAddressWithNetworkMask

+
+public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
+
+
Calculate the maximum address with the given network mask. +

+

+
+
+
+
Parameters:
networkMask - network mask +
Returns:
an address of which the last 128 - networkMask.asPrefixLength() bits are one
+
+
+
+ +

+toString

+
+public String toString()
+
+
+
Overrides:
toString in class Object
+
+
+ +
Returns:
String representation of the IPv6 address, using shorthand notation whenever possible.
+
+
+
+ +

+toLongString

+
+public String toLongString()
+
+
+
+
+
+ +
Returns:
String representation of the IPv6 address, never using shorthand notation.
+
+
+
+ +

+toShortArray

+
+public short[] toShortArray()
+
+
+
+
+
+
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
+
Overrides:
equals in class Object
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
Overrides:
hashCode in class Object
+
+
+
+
+
+
+ +

+compareTo

+
+public int compareTo(IPv6Address that)
+
+
+
Specified by:
compareTo in interface Comparable<IPv6Address>
+
+
+
+
+
+
+ +

+getHighBits

+
+public long getHighBits()
+
+
+
+
+
+
+
+
+
+ +

+getLowBits

+
+public long getLowBits()
+
+
+
+
+
+
+
+
+
+ +

+numberOfTrailingZeroes

+
+public int numberOfTrailingZeroes()
+
+
+
+
+
+
+
+
+
+ +

+numberOfTrailingOnes

+
+public int numberOfTrailingOnes()
+
+
+
+
+
+
+
+
+
+ +

+numberOfLeadingZeroes

+
+public int numberOfLeadingZeroes()
+
+
+
+
+
+
+
+
+
+ +

+numberOfLeadingOnes

+
+public int numberOfLeadingOnes()
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..93e1f3f --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,280 @@ + + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6AddressHelpers

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6AddressHelpers
+
+
+
+
public final class IPv6AddressHelpers
extends Object
+ + +

+Helper methods used by IPv6Address. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
IPv6AddressHelpers() + +
+           
+  + + + + + + + + + + + + + + + +
+Method Summary
+static intcountOccurrences(String haystack, + char needle) + +
+           
+static StringgenerateZeroes(int number) + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+IPv6AddressHelpers

+
+public IPv6AddressHelpers()
+
+
+ + + + + + + + +
+Method Detail
+ +

+countOccurrences

+
+public static int countOccurrences(String haystack,
+                                   char needle)
+
+
+
+
+
+
+ +

+generateZeroes

+
+public static String generateZeroes(int number)
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..a36ce84 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,561 @@ + + + + + + + +IPv6AddressPool (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6AddressPool

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6AddressPool
+
+
+
+
public final class IPv6AddressPool
extends Object
+ + +

+Immutable representation of an IPv6 address pool. +

+ An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ IPv6AddressPoolallocate() + +
+          Allocate the first available subnet from the pool.
+ IPv6AddressPoolallocate(IPv6Network toAllocate) + +
+          Allocate the given subnet from the pool.
+ booleancontains(IPv6Address address) + +
+           
+ booleancontains(IPv6AddressRange range) + +
+           
+ IPv6AddressPooldeAllocate(IPv6Network toDeAllocate) + +
+          Give a network back to the pool (de-allocate).
+ booleanequals(Object o) + +
+           
+ Iterable<IPv6Network>freeNetworks() + +
+           
+static IPv6AddressPoolfromRangeAndSubnet(IPv6AddressRange range, + IPv6NetworkMask allocationSubnetSize) + +
+          Create a pool of the given range (boundaries inclusive) which is completely free.
+ IPv6AddressgetFirst() + +
+           
+ IPv6AddressgetLast() + +
+           
+ IPv6NetworkgetLastAllocated() + +
+           
+ inthashCode() + +
+           
+ booleanisExhausted() + +
+           
+ booleanisFree(IPv6Network network) + +
+           
+ booleanoverlaps(IPv6AddressRange range) + +
+           
+ StringtoLongString() + +
+           
+ StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+fromRangeAndSubnet

+
+public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
+                                                 IPv6NetworkMask allocationSubnetSize)
+
+
Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). +

+

+
Parameters:
range - range from within to allocate
allocationSubnetSize - size of the subnets that will be allocated
+
+
+
+ +

+getLastAllocated

+
+public IPv6Network getLastAllocated()
+
+
+ +
Returns:
the last IPv6Network which was allocated or null if none was allocated yet
+
+
+
+ +

+allocate

+
+public IPv6AddressPool allocate()
+
+
Allocate the first available subnet from the pool. +

+

+ +
Returns:
resulting pool
+
+
+
+ +

+allocate

+
+public IPv6AddressPool allocate(IPv6Network toAllocate)
+
+
Allocate the given subnet from the pool. +

+

+
Parameters:
toAllocate - subnet to allocate from the pool +
Returns:
resulting pool
+
+
+
+ +

+deAllocate

+
+public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
+
+
Give a network back to the pool (de-allocate). +

+

+
Parameters:
toDeAllocate - network to de-allocate
+
+
+
+ +

+isExhausted

+
+public boolean isExhausted()
+
+
+ +
Returns:
true if no subnets are free in this pool, false otherwize
+
+
+
+ +

+isFree

+
+public boolean isFree(IPv6Network network)
+
+
+
+
+
+
+ +

+freeNetworks

+
+public Iterable<IPv6Network> freeNetworks()
+
+
+ +
Returns:
all networks (all with the same fixed prefix length) which are free in this pool
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
+
Overrides:
equals in class Object
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
Overrides:
hashCode in class Object
+
+
+
+
+
+
+ +

+contains

+
+public boolean contains(IPv6Address address)
+
+
+
+
+
+
+ +

+contains

+
+public boolean contains(IPv6AddressRange range)
+
+
+
+
+
+
+ +

+overlaps

+
+public boolean overlaps(IPv6AddressRange range)
+
+
+
+
+
+
+ +

+getFirst

+
+public IPv6Address getFirst()
+
+
+
+
+
+
+ +

+getLast

+
+public IPv6Address getLast()
+
+
+
+
+
+
+ +

+toString

+
+public String toString()
+
+
+
Overrides:
toString in class Object
+
+
+
+
+
+
+ +

+toLongString

+
+public String toLongString()
+
+
+ +
Returns:
like toString but without using shorthand notations for addresses
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..46d0154 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,561 @@ + + + + + + + +IPv6AddressRange (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6AddressRange

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6AddressRange
+
+
+
All Implemented Interfaces:
Comparable<IPv6AddressRange>, Iterable<IPv6Address>
+
+
+
Direct Known Subclasses:
IPv6Network
+
+
+
+
public class IPv6AddressRange
extends Object
implements Comparable<IPv6AddressRange>, Iterable<IPv6Address>
+ + +

+Immutable representation of a continuous range of IPv6 addresses (bounds included). +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ intcompareTo(IPv6AddressRange that) + +
+           
+ booleancontains(IPv6Address address) + +
+           
+ booleancontains(IPv6AddressRange range) + +
+           
+ booleanequals(Object o) + +
+           
+ IPv6AddressRangeextend(IPv6Address address) + +
+          Extend the range just enough at its head or tail such that the given address is included.
+static IPv6AddressRangefromFirstAndLast(IPv6Address first, + IPv6Address last) + +
+           
+ IPv6AddressgetFirst() + +
+           
+ IPv6AddressgetLast() + +
+           
+ inthashCode() + +
+           
+ Iterator<IPv6Address>iterator() + +
+           
+ booleanoverlaps(IPv6AddressRange range) + +
+           
+ List<IPv6AddressRange>remove(IPv6Address address) + +
+          Remove an address from the range, resulting in one, none or two new ranges.
+ List<IPv6AddressRange>remove(IPv6Network network) + +
+          Remove a network from the range, resulting in one, none or two new ranges.
+ StringtoLongString() + +
+           
+ StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+fromFirstAndLast

+
+public static IPv6AddressRange fromFirstAndLast(IPv6Address first,
+                                                IPv6Address last)
+
+
+
+
+
+
+
+
+
+ +

+contains

+
+public boolean contains(IPv6Address address)
+
+
+
+
+
+
+
+
+
+ +

+contains

+
+public boolean contains(IPv6AddressRange range)
+
+
+
+
+
+
+
+
+
+ +

+overlaps

+
+public boolean overlaps(IPv6AddressRange range)
+
+
+
+
+
+
+
+
+
+ +

+iterator

+
+public Iterator<IPv6Address> iterator()
+
+
+
Specified by:
iterator in interface Iterable<IPv6Address>
+
+
+ +
Returns:
an iterator which iterates all addresses in this range, in order.
+
+
+
+ +

+remove

+
+public List<IPv6AddressRange> remove(IPv6Address address)
+
+
Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned. +

+

+
+
+
+
Parameters:
address - adddress to remove from the range +
Returns:
list of resulting ranges
+
+
+
+ +

+extend

+
+public IPv6AddressRange extend(IPv6Address address)
+
+
Extend the range just enough at its head or tail such that the given address is included. +

+

+
+
+
+
Parameters:
address - address to extend the range to +
Returns:
new (bigger) range
+
+
+
+ +

+remove

+
+public List<IPv6AddressRange> remove(IPv6Network network)
+
+
Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned. +

+

+
+
+
+
Parameters:
network - network to remove from the range +
Returns:
list of resulting ranges
+
+
+
+ +

+toString

+
+public String toString()
+
+
+
Overrides:
toString in class Object
+
+
+
+
+
+
+ +

+toLongString

+
+public String toLongString()
+
+
+
+
+
+ +
Returns:
like toString but without using shorthand notations for addresses
+
+
+
+ +

+compareTo

+
+public int compareTo(IPv6AddressRange that)
+
+
+
Specified by:
compareTo in interface Comparable<IPv6AddressRange>
+
+
+
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
+
Overrides:
equals in class Object
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
Overrides:
hashCode in class Object
+
+
+
+
+
+
+ +

+getFirst

+
+public IPv6Address getFirst()
+
+
+
+
+
+
+
+
+
+ +

+getLast

+
+public IPv6Address getLast()
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..3dc3855 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,399 @@ + + + + + + + +IPv6Network (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6Network

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6AddressRange
+      extended by com.googlecode.ipv6.IPv6Network
+
+
+
All Implemented Interfaces:
Comparable<IPv6AddressRange>, Iterable<IPv6Address>
+
+
+
+
public final class IPv6Network
extends IPv6AddressRange
+ + +

+Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks). +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleanequals(Object o) + +
+           
+static IPv6NetworkfromAddressAndMask(IPv6Address address, + IPv6NetworkMask networkMask) + +
+          Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+static IPv6NetworkfromString(String string) + +
+          Create an IPv6 network from its String representation.
+static IPv6NetworkfromTwoAddresses(IPv6Address one, + IPv6Address two) + +
+          Create an IPv6 network from the two addresses within the network.
+ IPv6NetworkMaskgetNetmask() + +
+           
+ inthashCode() + +
+           
+ StringtoLongString() + +
+           
+ StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class com.googlecode.ipv6.IPv6AddressRange
compareTo, contains, contains, extend, fromFirstAndLast, getFirst, getLast, iterator, overlaps, remove, remove
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+fromAddressAndMask

+
+public static IPv6Network fromAddressAndMask(IPv6Address address,
+                                             IPv6NetworkMask networkMask)
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask +

+

+
Parameters:
address - IPv6 address (the network address or any other address within the network)
networkMask - IPv6 network mask +
Returns:
IPv6 network
+
+
+
+ +

+fromTwoAddresses

+
+public static IPv6Network fromTwoAddresses(IPv6Address one,
+                                           IPv6Address two)
+
+
Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses. +

+

+
Parameters:
one - address one
two - address two, should be bigger than address one
+
+
+
+ +

+fromString

+
+public static IPv6Network fromString(String string)
+
+
Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". +

+

+
Parameters:
string - string representation +
Returns:
IPv6 network
+
+
+
+ +

+toString

+
+public String toString()
+
+
+
Overrides:
toString in class IPv6AddressRange
+
+
+
+
+
+
+ +

+toLongString

+
+public String toLongString()
+
+
+
Overrides:
toLongString in class IPv6AddressRange
+
+
+ +
Returns:
like toString but without using shorthand notations for addresses
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
+
Overrides:
equals in class IPv6AddressRange
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
Overrides:
hashCode in class IPv6AddressRange
+
+
+
+
+
+
+ +

+getNetmask

+
+public IPv6NetworkMask getNetmask()
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..7214637 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6NetworkHelpers

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6NetworkHelpers
+
+
+
+
public class IPv6NetworkHelpers
extends Object
+ + +

+Helper methods used by IPv6Network. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
IPv6NetworkHelpers() + +
+           
+  + + + + + + + +
+Method Summary
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+IPv6NetworkHelpers

+
+public IPv6NetworkHelpers()
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..5b51e9b --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,358 @@ + + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6NetworkMask

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6NetworkMask
+
+
+
+
public final class IPv6NetworkMask
extends Object
+ + +

+Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ IPv6AddressasAddress() + +
+           
+ intasPrefixLength() + +
+           
+ booleanequals(Object o) + +
+           
+static IPv6NetworkMaskfromAddress(IPv6Address iPv6Address) + +
+          Construct an IPv6 network mask from an IPv6 address.
+static IPv6NetworkMaskfromPrefixLength(int prefixLength) + +
+          Construct an IPv6 network mask from a prefix length.
+ inthashCode() + +
+           
+ StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+fromAddress

+
+public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
+
+
Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. +

+

+
Parameters:
iPv6Address - address to use as network mask +
Throws: +
IllegalArgumentException - if the address is not a valid network mask
+
+
+
+ +

+fromPrefixLength

+
+public static IPv6NetworkMask fromPrefixLength(int prefixLength)
+
+
Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. +

+

+
Parameters:
prefixLength - prefix length +
Throws: +
IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
+
+
+
+ +

+asPrefixLength

+
+public int asPrefixLength()
+
+
+
+
+
+
+ +

+asAddress

+
+public IPv6Address asAddress()
+
+
+
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
+
Overrides:
equals in class Object
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
Overrides:
hashCode in class Object
+
+
+
+
+
+
+ +

+toString

+
+public String toString()
+
+
+
Overrides:
toString in class Object
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/BitSetHelpers.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/BitSetHelpers.html new file mode 100644 index 0000000..f380862 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/BitSetHelpers.html @@ -0,0 +1,143 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.BitSetHelpers (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.BitSetHelpers

+
+No usage of com.googlecode.ipv6.BitSetHelpers +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..0b26697 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,345 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6Address

+
+ + + + + +
+Uses of IPv6Address in com.googlecode.ipv6
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return IPv6Address
+ IPv6AddressIPv6Address.add(int value) + +
+          Addition.
+ IPv6AddressIPv6NetworkMask.asAddress() + +
+           
+static IPv6AddressIPv6Address.fromInetAddress(InetAddress inetAddress) + +
+          Create an IPv6 address from a java.net.Inet6Address.
+static IPv6AddressIPv6Address.fromString(String string) + +
+          Create an IPv6 address from its String representation.
+ IPv6AddressIPv6AddressRange.getFirst() + +
+           
+ IPv6AddressIPv6AddressPool.getFirst() + +
+           
+ IPv6AddressIPv6AddressRange.getLast() + +
+           
+ IPv6AddressIPv6AddressPool.getLast() + +
+           
+ IPv6AddressIPv6Address.maskWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Mask the address with the given network mask.
+ IPv6AddressIPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Calculate the maximum address with the given network mask.
+ IPv6AddressIPv6Address.subtract(int value) + +
+          Subtraction.
+  +

+ + + + + + + + + +
Methods in com.googlecode.ipv6 that return types with arguments of type IPv6Address
+ Iterator<IPv6Address>IPv6AddressRange.iterator() + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 with parameters of type IPv6Address
+ intIPv6Address.compareTo(IPv6Address that) + +
+           
+ booleanIPv6AddressRange.contains(IPv6Address address) + +
+           
+ booleanIPv6AddressPool.contains(IPv6Address address) + +
+           
+ IPv6AddressRangeIPv6AddressRange.extend(IPv6Address address) + +
+          Extend the range just enough at its head or tail such that the given address is included.
+static IPv6NetworkMaskIPv6NetworkMask.fromAddress(IPv6Address iPv6Address) + +
+          Construct an IPv6 network mask from an IPv6 address.
+static IPv6NetworkIPv6Network.fromAddressAndMask(IPv6Address address, + IPv6NetworkMask networkMask) + +
+          Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+static IPv6AddressRangeIPv6AddressRange.fromFirstAndLast(IPv6Address first, + IPv6Address last) + +
+           
+static IPv6NetworkIPv6Network.fromTwoAddresses(IPv6Address one, + IPv6Address two) + +
+          Create an IPv6 network from the two addresses within the network.
+ List<IPv6AddressRange>IPv6AddressRange.remove(IPv6Address address) + +
+          Remove an address from the range, resulting in one, none or two new ranges.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..c765e9d --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,143 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+No usage of com.googlecode.ipv6.IPv6AddressHelpers +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..512c7c3 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,191 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+ + + + + +
+Uses of IPv6AddressPool in com.googlecode.ipv6
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return IPv6AddressPool
+ IPv6AddressPoolIPv6AddressPool.allocate() + +
+          Allocate the first available subnet from the pool.
+ IPv6AddressPoolIPv6AddressPool.allocate(IPv6Network toAllocate) + +
+          Allocate the given subnet from the pool.
+ IPv6AddressPoolIPv6AddressPool.deAllocate(IPv6Network toDeAllocate) + +
+          Give a network back to the pool (de-allocate).
+static IPv6AddressPoolIPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange range, + IPv6NetworkMask allocationSubnetSize) + +
+          Create a pool of the given range (boundaries inclusive) which is completely free.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..d1d09ef --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,272 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+ + + + + +
+Uses of IPv6AddressRange in com.googlecode.ipv6
+  +

+ + + + + + + + + +
Subclasses of IPv6AddressRange in com.googlecode.ipv6
+ classIPv6Network + +
+          Immutable representation of an IPv6 network based on an address and a prefix length.
+  +

+ + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return IPv6AddressRange
+ IPv6AddressRangeIPv6AddressRange.extend(IPv6Address address) + +
+          Extend the range just enough at its head or tail such that the given address is included.
+static IPv6AddressRangeIPv6AddressRange.fromFirstAndLast(IPv6Address first, + IPv6Address last) + +
+           
+  +

+ + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return types with arguments of type IPv6AddressRange
+ List<IPv6AddressRange>IPv6AddressRange.remove(IPv6Address address) + +
+          Remove an address from the range, resulting in one, none or two new ranges.
+ List<IPv6AddressRange>IPv6AddressRange.remove(IPv6Network network) + +
+          Remove a network from the range, resulting in one, none or two new ranges.
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 with parameters of type IPv6AddressRange
+ intIPv6AddressRange.compareTo(IPv6AddressRange that) + +
+           
+ booleanIPv6AddressRange.contains(IPv6AddressRange range) + +
+           
+ booleanIPv6AddressPool.contains(IPv6AddressRange range) + +
+           
+static IPv6AddressPoolIPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange range, + IPv6NetworkMask allocationSubnetSize) + +
+          Create a pool of the given range (boundaries inclusive) which is completely free.
+ booleanIPv6AddressRange.overlaps(IPv6AddressRange range) + +
+           
+ booleanIPv6AddressPool.overlaps(IPv6AddressRange range) + +
+           
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..b174196 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,248 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6Network

+
+ + + + + +
+Uses of IPv6Network in com.googlecode.ipv6
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return IPv6Network
+static IPv6NetworkIPv6Network.fromAddressAndMask(IPv6Address address, + IPv6NetworkMask networkMask) + +
+          Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+static IPv6NetworkIPv6Network.fromString(String string) + +
+          Create an IPv6 network from its String representation.
+static IPv6NetworkIPv6Network.fromTwoAddresses(IPv6Address one, + IPv6Address two) + +
+          Create an IPv6 network from the two addresses within the network.
+ IPv6NetworkIPv6AddressPool.getLastAllocated() + +
+           
+  +

+ + + + + + + + + +
Methods in com.googlecode.ipv6 that return types with arguments of type IPv6Network
+ Iterable<IPv6Network>IPv6AddressPool.freeNetworks() + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 with parameters of type IPv6Network
+ IPv6AddressPoolIPv6AddressPool.allocate(IPv6Network toAllocate) + +
+          Allocate the given subnet from the pool.
+ IPv6AddressPoolIPv6AddressPool.deAllocate(IPv6Network toDeAllocate) + +
+          Give a network back to the pool (de-allocate).
+ booleanIPv6AddressPool.isFree(IPv6Network network) + +
+           
+ List<IPv6AddressRange>IPv6AddressRange.remove(IPv6Network network) + +
+          Remove a network from the range, resulting in one, none or two new ranges.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..dcd35ad --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,143 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+No usage of com.googlecode.ipv6.IPv6NetworkHelpers +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..5663f98 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,224 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+ + + + + +
+Uses of IPv6NetworkMask in com.googlecode.ipv6
+  +

+ + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return IPv6NetworkMask
+static IPv6NetworkMaskIPv6NetworkMask.fromAddress(IPv6Address iPv6Address) + +
+          Construct an IPv6 network mask from an IPv6 address.
+static IPv6NetworkMaskIPv6NetworkMask.fromPrefixLength(int prefixLength) + +
+          Construct an IPv6 network mask from a prefix length.
+ IPv6NetworkMaskIPv6Network.getNetmask() + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 with parameters of type IPv6NetworkMask
+static IPv6NetworkIPv6Network.fromAddressAndMask(IPv6Address address, + IPv6NetworkMask networkMask) + +
+          Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+static IPv6AddressPoolIPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange range, + IPv6NetworkMask allocationSubnetSize) + +
+          Create a pool of the given range (boundaries inclusive) which is completely free.
+ IPv6AddressIPv6Address.maskWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Mask the address with the given network mask.
+ IPv6AddressIPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Calculate the maximum address with the given network mask.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..e97fa86 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,47 @@ + + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.7 API) + + + + + + + + + + + +com.googlecode.ipv6 + + + + +
+Classes  + +
+BitSetHelpers +
+IPv6Address +
+IPv6AddressHelpers +
+IPv6AddressPool +
+IPv6AddressRange +
+IPv6Network +
+IPv6NetworkHelpers +
+IPv6NetworkMask
+ + + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..94fab0f --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,184 @@ + + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package com.googlecode.ipv6 +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Class Summary
BitSetHelpersThis class contains some helpers for working with BitSets.
IPv6AddressImmutable representation of an IPv6 address.
IPv6AddressHelpersHelper methods used by IPv6Address.
IPv6AddressPoolImmutable representation of an IPv6 address pool.
IPv6AddressRangeImmutable representation of a continuous range of IPv6 addresses (bounds included).
IPv6NetworkImmutable representation of an IPv6 network based on an address and a prefix length.
IPv6NetworkHelpersHelper methods used by IPv6Network.
IPv6NetworkMaskImmutable representation of an IPv6 network mask.
+  + +

+

+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..95f07aa --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,153 @@ + + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package com.googlecode.ipv6 +

+
+

+Class Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..1c2947e --- /dev/null +++ b/artifacts/0.7/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,180 @@ + + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
com.googlecode.ipv6

+
+ + + + + + + + + + + + + + + + + + + + +
+Classes in com.googlecode.ipv6 used by com.googlecode.ipv6
IPv6Address + +
+          Immutable representation of an IPv6 address.
IPv6AddressPool + +
+          Immutable representation of an IPv6 address pool.
IPv6AddressRange + +
+          Immutable representation of a continuous range of IPv6 addresses (bounds included).
IPv6Network + +
+          Immutable representation of an IPv6 network based on an address and a prefix length.
IPv6NetworkMask + +
+          Immutable representation of an IPv6 network mask.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/constant-values.html b/artifacts/0.7/doc/apidocs/constant-values.html new file mode 100644 index 0000000..cd0f2b3 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/constant-values.html @@ -0,0 +1,145 @@ + + + + + + + +Constant Field Values (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Constant Field Values

+
+
+Contents
    +
+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/deprecated-list.html b/artifacts/0.7/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..cfcbbe8 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/deprecated-list.html @@ -0,0 +1,145 @@ + + + + + + + +Deprecated List (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Deprecated API

+
+
+Contents
    +
+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/help-doc.html b/artifacts/0.7/doc/apidocs/help-doc.html new file mode 100644 index 0000000..2ad4af3 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + + +API Help (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+How This API Document Is Organized

+
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.

+Package

+
+ +

+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:

    +
  • Interfaces (italic)
  • Classes
  • Enums
  • Exceptions
  • Errors
  • Annotation Types
+
+

+Class/Interface

+
+ +

+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
  • Class inheritance diagram
  • Direct Subclasses
  • All Known Subinterfaces
  • All Known Implementing Classes
  • Class/interface declaration
  • Class/interface description +

    +

  • Nested Class Summary
  • Field Summary
  • Constructor Summary
  • Method Summary +

    +

  • Field Detail
  • Constructor Detail
  • Method Detail
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+ +

+Annotation Type

+
+ +

+Each annotation type has its own separate page with the following sections:

    +
  • Annotation Type declaration
  • Annotation Type description
  • Required Element Summary
  • Optional Element Summary
  • Element Detail
+
+ +

+Enum

+
+ +

+Each enum has its own separate page with the following sections:

    +
  • Enum declaration
  • Enum description
  • Enum Constant Summary
  • Enum Constant Detail
+
+

+Use

+
+Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+

+Tree (Class Hierarchy)

+
+There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
    +
  • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
  • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+

+Deprecated API

+
+The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+

+Index

+
+The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+

+Prev/Next

+These links take you to the next or previous class, interface, package, or related page.

+Frames/No Frames

+These links show and hide the HTML frames. All pages are available with or without frames. +

+

+Serialized Form

+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description. +

+

+Constant Field Values

+The Constant Field Values page lists the static final fields and their values. +

+ + +This help file applies to API documentation generated using the standard doclet. + +
+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/index-all.html b/artifacts/0.7/doc/apidocs/index-all.html new file mode 100644 index 0000000..68dc262 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/index-all.html @@ -0,0 +1,424 @@ + + + + + + + +Index (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A B C D E F G H I M N O R S T
+

+A

+
+
add(int) - +Method in class com.googlecode.ipv6.IPv6Address +
Addition. +
allocate() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
Allocate the first available subnet from the pool. +
allocate(IPv6Network) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
Allocate the given subnet from the pool. +
asAddress() - +Method in class com.googlecode.ipv6.IPv6NetworkMask +
  +
asPrefixLength() - +Method in class com.googlecode.ipv6.IPv6NetworkMask +
  +
+
+

+B

+
+
BitSetHelpers - Class in com.googlecode.ipv6
This class contains some helpers for working with BitSets.
BitSetHelpers() - +Constructor for class com.googlecode.ipv6.BitSetHelpers +
  +
+
+

+C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
 
compareTo(IPv6Address) - +Method in class com.googlecode.ipv6.IPv6Address +
  +
compareTo(IPv6AddressRange) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
contains(IPv6Address) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
contains(IPv6AddressRange) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
contains(IPv6Address) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
contains(IPv6AddressRange) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
countOccurrences(String, char) - +Static method in class com.googlecode.ipv6.IPv6AddressHelpers +
  +
+
+

+D

+
+
deAllocate(IPv6Network) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
Give a network back to the pool (de-allocate). +
+
+

+E

+
+
equals(Object) - +Method in class com.googlecode.ipv6.IPv6Address +
  +
equals(Object) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
equals(Object) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
equals(Object) - +Method in class com.googlecode.ipv6.IPv6Network +
  +
equals(Object) - +Method in class com.googlecode.ipv6.IPv6NetworkMask +
  +
extend(IPv6Address) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
Extend the range just enough at its head or tail such that the given address is included. +
+
+

+F

+
+
freeNetworks() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
fromAddress(IPv6Address) - +Static method in class com.googlecode.ipv6.IPv6NetworkMask +
Construct an IPv6 network mask from an IPv6 address. +
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - +Static method in class com.googlecode.ipv6.IPv6Network +
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask +
fromFirstAndLast(IPv6Address, IPv6Address) - +Static method in class com.googlecode.ipv6.IPv6AddressRange +
  +
fromInetAddress(InetAddress) - +Static method in class com.googlecode.ipv6.IPv6Address +
Create an IPv6 address from a java.net.Inet6Address. +
fromPrefixLength(int) - +Static method in class com.googlecode.ipv6.IPv6NetworkMask +
Construct an IPv6 network mask from a prefix length. +
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - +Static method in class com.googlecode.ipv6.IPv6AddressPool +
Create a pool of the given range (boundaries inclusive) which is completely free. +
fromString(String) - +Static method in class com.googlecode.ipv6.IPv6Address +
Create an IPv6 address from its String representation. +
fromString(String) - +Static method in class com.googlecode.ipv6.IPv6Network +
Create an IPv6 network from its String representation. +
fromTwoAddresses(IPv6Address, IPv6Address) - +Static method in class com.googlecode.ipv6.IPv6Network +
Create an IPv6 network from the two addresses within the network. +
+
+

+G

+
+
generateZeroes(int) - +Static method in class com.googlecode.ipv6.IPv6AddressHelpers +
  +
getFirst() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
getFirst() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
getHighBits() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
getLast() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
getLast() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
getLastAllocated() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
getLowBits() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
getNetmask() - +Method in class com.googlecode.ipv6.IPv6Network +
  +
+
+

+H

+
+
hashCode() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
hashCode() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
hashCode() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
hashCode() - +Method in class com.googlecode.ipv6.IPv6Network +
  +
hashCode() - +Method in class com.googlecode.ipv6.IPv6NetworkMask +
  +
+
+

+I

+
+
IPv6Address - Class in com.googlecode.ipv6
Immutable representation of an IPv6 address.
IPv6AddressHelpers - Class in com.googlecode.ipv6
Helper methods used by IPv6Address.
IPv6AddressHelpers() - +Constructor for class com.googlecode.ipv6.IPv6AddressHelpers +
  +
IPv6AddressPool - Class in com.googlecode.ipv6
Immutable representation of an IPv6 address pool.
IPv6AddressRange - Class in com.googlecode.ipv6
Immutable representation of a continuous range of IPv6 addresses (bounds included).
IPv6Network - Class in com.googlecode.ipv6
Immutable representation of an IPv6 network based on an address and a prefix length.
IPv6NetworkHelpers - Class in com.googlecode.ipv6
Helper methods used by IPv6Network.
IPv6NetworkHelpers() - +Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers +
  +
IPv6NetworkMask - Class in com.googlecode.ipv6
Immutable representation of an IPv6 network mask.
isExhausted() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
isFree(IPv6Network) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
iterator() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
+
+

+M

+
+
maskWithNetworkMask(IPv6NetworkMask) - +Method in class com.googlecode.ipv6.IPv6Address +
Mask the address with the given network mask. +
maximumAddressWithNetworkMask(IPv6NetworkMask) - +Method in class com.googlecode.ipv6.IPv6Address +
Calculate the maximum address with the given network mask. +
+
+

+N

+
+
numberOfLeadingOnes() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
numberOfLeadingZeroes() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
numberOfTrailingOnes() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
numberOfTrailingZeroes() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
+
+

+O

+
+
overlaps(IPv6AddressRange) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
overlaps(IPv6AddressRange) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
+
+

+R

+
+
remove(IPv6Address) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
Remove an address from the range, resulting in one, none or two new ranges. +
remove(IPv6Network) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
Remove a network from the range, resulting in one, none or two new ranges. +
+
+

+S

+
+
subtract(int) - +Method in class com.googlecode.ipv6.IPv6Address +
Subtraction. +
+
+

+T

+
+
toInetAddress() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
toLongString() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
toLongString() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
toLongString() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
toLongString() - +Method in class com.googlecode.ipv6.IPv6Network +
  +
toShortArray() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
toString() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
toString() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
toString() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
toString() - +Method in class com.googlecode.ipv6.IPv6Network +
  +
toString() - +Method in class com.googlecode.ipv6.IPv6NetworkMask +
  +
+
+A B C D E F G H I M N O R S T + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/index.html b/artifacts/0.7/doc/apidocs/index.html new file mode 100644 index 0000000..53bd1da --- /dev/null +++ b/artifacts/0.7/doc/apidocs/index.html @@ -0,0 +1,37 @@ + + + + + + + +Java IPv6 Library 0.7 API + + + + + + + + +<H2> +Frame Alert</H2> + +<P> +This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. +<BR> +Link to<A HREF="com/googlecode/ipv6/package-summary.html">Non-frame version.</A> + + + diff --git a/artifacts/0.7/doc/apidocs/overview-tree.html b/artifacts/0.7/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..717a0e8 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/overview-tree.html @@ -0,0 +1,155 @@ + + + + + + + +Class Hierarchy (Java IPv6 Library 0.7 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For All Packages

+
+
+
Package Hierarchies:
com.googlecode.ipv6
+
+

+Class Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.7/doc/apidocs/package-list b/artifacts/0.7/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.7/doc/apidocs/resources/inherit.gif b/artifacts/0.7/doc/apidocs/resources/inherit.gif new file mode 100644 index 0000000000000000000000000000000000000000..c814867a13deb0ca7ea2156c6ca1d5a03372af7e GIT binary patch literal 57 zcmZ?wbhEHbIIT!9-C*e{wE9>Kx3D)-;0v)C; KYxQGgum%9JOA&7X literal 0 HcmV?d00001 diff --git a/artifacts/0.7/doc/apidocs/stylesheet.css b/artifacts/0.7/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..6ea9e51 --- /dev/null +++ b/artifacts/0.7/doc/apidocs/stylesheet.css @@ -0,0 +1,29 @@ +/* Javadoc style sheet */ + +/* Define colors, fonts and other style attributes here to override the defaults */ + +/* Page background color */ +body { background-color: #FFFFFF; color:#000000 } + +/* Headings */ +h1 { font-size: 145% } + +/* Table colors */ +.TableHeadingColor { background: #CCCCFF; color:#000000 } /* Dark mauve */ +.TableSubHeadingColor { background: #EEEEFF; color:#000000 } /* Light mauve */ +.TableRowColor { background: #FFFFFF; color:#000000 } /* White */ + +/* Font used in left-hand frame lists */ +.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif; color:#000000 } +.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 } +.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 } + +/* Navigation bar fonts and colors */ +.NavBarCell1 { background-color:#EEEEFF; color:#000000} /* Light mauve */ +.NavBarCell1Rev { background-color:#00008B; color:#FFFFFF} /* Dark Blue */ +.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;color:#000000;} +.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;color:#FFFFFF;} + +.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000} +.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000} + diff --git a/artifacts/0.8/doc/apidocs/allclasses-frame.html b/artifacts/0.8/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..fbc48b7 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/allclasses-frame.html @@ -0,0 +1,44 @@ + + + + + + + +All Classes (Java IPv6 Library 0.8 API) + + + + + + + + + + + +All Classes +
+ + + + + +
IPv6Address +
+IPv6AddressHelpers +
+IPv6AddressPool +
+IPv6AddressRange +
+IPv6Network +
+IPv6NetworkHelpers +
+IPv6NetworkMask +
+
+ + + diff --git a/artifacts/0.8/doc/apidocs/allclasses-noframe.html b/artifacts/0.8/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..4bce8d3 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,44 @@ + + + + + + + +All Classes (Java IPv6 Library 0.8 API) + + + + + + + + + + + +All Classes +
+ + + + + +
IPv6Address +
+IPv6AddressHelpers +
+IPv6AddressPool +
+IPv6AddressRange +
+IPv6Network +
+IPv6NetworkHelpers +
+IPv6NetworkMask +
+
+ + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..e20180e --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,652 @@ + + + + + + + +IPv6Address (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6Address

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6Address
+
+
+
All Implemented Interfaces:
Comparable<IPv6Address>
+
+
+
+
public final class IPv6Address
extends Object
implements Comparable<IPv6Address>
+ + +

+Immutable representation of an IPv6 address. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ IPv6Addressadd(int value) + +
+          Addition.
+ intcompareTo(IPv6Address that) + +
+           
+ booleanequals(Object o) + +
+           
+static IPv6AddressfromInetAddress(InetAddress inetAddress) + +
+          Create an IPv6 address from a java.net.Inet6Address.
+static IPv6AddressfromString(String string) + +
+          Create an IPv6 address from its String representation.
+ longgetHighBits() + +
+           
+ longgetLowBits() + +
+           
+ inthashCode() + +
+           
+ IPv6AddressmaskWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Mask the address with the given network mask.
+ IPv6AddressmaximumAddressWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Calculate the maximum address with the given network mask.
+ intnumberOfLeadingOnes() + +
+           
+ intnumberOfLeadingZeroes() + +
+           
+ intnumberOfTrailingOnes() + +
+           
+ intnumberOfTrailingZeroes() + +
+           
+ IPv6Addresssubtract(int value) + +
+          Subtraction.
+ InetAddresstoInetAddress() + +
+           
+ StringtoLongString() + +
+           
+ short[]toShortArray() + +
+           
+ StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+fromString

+
+public static IPv6Address fromString(String string)
+
+
Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::". +

+

+
+
+
+
Parameters:
string - string representation +
Returns:
IPv6 address
+
+
+
+ +

+fromInetAddress

+
+public static IPv6Address fromInetAddress(InetAddress inetAddress)
+
+
Create an IPv6 address from a java.net.Inet6Address. +

+

+
+
+
+
Parameters:
inetAddress - Inet6Address representation +
Returns:
IPv6 address
+
+
+
+ +

+toInetAddress

+
+public InetAddress toInetAddress()
+                          throws UnknownHostException
+
+
+
+
+
+ +
Throws: +
UnknownHostException
+
+
+
+ +

+add

+
+public IPv6Address add(int value)
+
+
Addition. Will never overflow, but wraps around when the highest ip address has been reached. +

+

+
+
+
+
Parameters:
value - value to add +
Returns:
new IPv6 address
+
+
+
+ +

+subtract

+
+public IPv6Address subtract(int value)
+
+
Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. +

+

+
+
+
+
Parameters:
value - value to substract +
Returns:
new IPv6 address
+
+
+
+ +

+maskWithNetworkMask

+
+public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
+
+
Mask the address with the given network mask. +

+

+
+
+
+
Parameters:
networkMask - network mask +
Returns:
an address of which the last 128 - networkMask.asPrefixLength() bits are zero
+
+
+
+ +

+maximumAddressWithNetworkMask

+
+public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
+
+
Calculate the maximum address with the given network mask. +

+

+
+
+
+
Parameters:
networkMask - network mask +
Returns:
an address of which the last 128 - networkMask.asPrefixLength() bits are one
+
+
+
+ +

+toString

+
+public String toString()
+
+
+
Overrides:
toString in class Object
+
+
+ +
Returns:
String representation of the IPv6 address, using shorthand notation whenever possible.
+
+
+
+ +

+toLongString

+
+public String toLongString()
+
+
+
+
+
+ +
Returns:
String representation of the IPv6 address, never using shorthand notation.
+
+
+
+ +

+toShortArray

+
+public short[] toShortArray()
+
+
+
+
+
+
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
+
Overrides:
equals in class Object
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
Overrides:
hashCode in class Object
+
+
+
+
+
+
+ +

+compareTo

+
+public int compareTo(IPv6Address that)
+
+
+
Specified by:
compareTo in interface Comparable<IPv6Address>
+
+
+
+
+
+
+ +

+getHighBits

+
+public long getHighBits()
+
+
+
+
+
+
+
+
+
+ +

+getLowBits

+
+public long getLowBits()
+
+
+
+
+
+
+
+
+
+ +

+numberOfTrailingZeroes

+
+public int numberOfTrailingZeroes()
+
+
+
+
+
+
+
+
+
+ +

+numberOfTrailingOnes

+
+public int numberOfTrailingOnes()
+
+
+
+
+
+
+
+
+
+ +

+numberOfLeadingZeroes

+
+public int numberOfLeadingZeroes()
+
+
+
+
+
+
+
+
+
+ +

+numberOfLeadingOnes

+
+public int numberOfLeadingOnes()
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..a64edd1 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,280 @@ + + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6AddressHelpers

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6AddressHelpers
+
+
+
+
public final class IPv6AddressHelpers
extends Object
+ + +

+Helper methods used by IPv6Address. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
IPv6AddressHelpers() + +
+           
+  + + + + + + + + + + + + + + + +
+Method Summary
+static intcountOccurrences(String haystack, + char needle) + +
+           
+static StringgenerateZeroes(int number) + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+IPv6AddressHelpers

+
+public IPv6AddressHelpers()
+
+
+ + + + + + + + +
+Method Detail
+ +

+countOccurrences

+
+public static int countOccurrences(String haystack,
+                                   char needle)
+
+
+
+
+
+
+ +

+generateZeroes

+
+public static String generateZeroes(int number)
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..63059ae --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,561 @@ + + + + + + + +IPv6AddressPool (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6AddressPool

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6AddressPool
+
+
+
+
public final class IPv6AddressPool
extends Object
+ + +

+Immutable representation of an IPv6 address pool. +

+ An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ IPv6AddressPoolallocate() + +
+          Allocate the first available subnet from the pool.
+ IPv6AddressPoolallocate(IPv6Network toAllocate) + +
+          Allocate the given subnet from the pool.
+ booleancontains(IPv6Address address) + +
+           
+ booleancontains(IPv6AddressRange range) + +
+           
+ IPv6AddressPooldeAllocate(IPv6Network toDeAllocate) + +
+          Give a network back to the pool (de-allocate).
+ booleanequals(Object o) + +
+           
+ Iterable<IPv6Network>freeNetworks() + +
+           
+static IPv6AddressPoolfromRangeAndSubnet(IPv6AddressRange range, + IPv6NetworkMask allocationSubnetSize) + +
+          Create a pool of the given range (boundaries inclusive) which is completely free.
+ IPv6AddressgetFirst() + +
+           
+ IPv6AddressgetLast() + +
+           
+ IPv6NetworkgetLastAllocated() + +
+           
+ inthashCode() + +
+           
+ booleanisExhausted() + +
+           
+ booleanisFree(IPv6Network network) + +
+           
+ booleanoverlaps(IPv6AddressRange range) + +
+           
+ StringtoLongString() + +
+           
+ StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+fromRangeAndSubnet

+
+public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
+                                                 IPv6NetworkMask allocationSubnetSize)
+
+
Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). +

+

+
Parameters:
range - range from within to allocate
allocationSubnetSize - size of the subnets that will be allocated
+
+
+
+ +

+getLastAllocated

+
+public IPv6Network getLastAllocated()
+
+
+ +
Returns:
the last IPv6Network which was allocated or null if none was allocated yet
+
+
+
+ +

+allocate

+
+public IPv6AddressPool allocate()
+
+
Allocate the first available subnet from the pool. +

+

+ +
Returns:
resulting pool
+
+
+
+ +

+allocate

+
+public IPv6AddressPool allocate(IPv6Network toAllocate)
+
+
Allocate the given subnet from the pool. +

+

+
Parameters:
toAllocate - subnet to allocate from the pool +
Returns:
resulting pool
+
+
+
+ +

+deAllocate

+
+public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
+
+
Give a network back to the pool (de-allocate). +

+

+
Parameters:
toDeAllocate - network to de-allocate
+
+
+
+ +

+isExhausted

+
+public boolean isExhausted()
+
+
+ +
Returns:
true if no subnets are free in this pool, false otherwize
+
+
+
+ +

+isFree

+
+public boolean isFree(IPv6Network network)
+
+
+
+
+
+
+ +

+freeNetworks

+
+public Iterable<IPv6Network> freeNetworks()
+
+
+ +
Returns:
all networks (all with the same fixed prefix length) which are free in this pool
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
+
Overrides:
equals in class Object
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
Overrides:
hashCode in class Object
+
+
+
+
+
+
+ +

+contains

+
+public boolean contains(IPv6Address address)
+
+
+
+
+
+
+ +

+contains

+
+public boolean contains(IPv6AddressRange range)
+
+
+
+
+
+
+ +

+overlaps

+
+public boolean overlaps(IPv6AddressRange range)
+
+
+
+
+
+
+ +

+getFirst

+
+public IPv6Address getFirst()
+
+
+
+
+
+
+ +

+getLast

+
+public IPv6Address getLast()
+
+
+
+
+
+
+ +

+toString

+
+public String toString()
+
+
+
Overrides:
toString in class Object
+
+
+
+
+
+
+ +

+toLongString

+
+public String toLongString()
+
+
+ +
Returns:
like toString but without using shorthand notations for addresses
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..6f34637 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,568 @@ + + + + + + + +IPv6AddressRange (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6AddressRange

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6AddressRange
+
+
+
All Implemented Interfaces:
Comparable<IPv6AddressRange>, Iterable<IPv6Address>
+
+
+
Direct Known Subclasses:
IPv6Network
+
+
+
+
public class IPv6AddressRange
extends Object
implements Comparable<IPv6AddressRange>, Iterable<IPv6Address>
+ + +

+Immutable representation of a continuous range of IPv6 addresses (bounds included). +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ intcompareTo(IPv6AddressRange that) + +
+          The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal.
+ booleancontains(IPv6Address address) + +
+           
+ booleancontains(IPv6AddressRange range) + +
+           
+ booleanequals(Object o) + +
+           
+ IPv6AddressRangeextend(IPv6Address address) + +
+          Extend the range just enough at its head or tail such that the given address is included.
+static IPv6AddressRangefromFirstAndLast(IPv6Address first, + IPv6Address last) + +
+           
+ IPv6AddressgetFirst() + +
+           
+ IPv6AddressgetLast() + +
+           
+ inthashCode() + +
+           
+ Iterator<IPv6Address>iterator() + +
+           
+ booleanoverlaps(IPv6AddressRange range) + +
+           
+ List<IPv6AddressRange>remove(IPv6Address address) + +
+          Remove an address from the range, resulting in one, none or two new ranges.
+ List<IPv6AddressRange>remove(IPv6Network network) + +
+          Remove a network from the range, resulting in one, none or two new ranges.
+ StringtoLongString() + +
+           
+ StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+fromFirstAndLast

+
+public static IPv6AddressRange fromFirstAndLast(IPv6Address first,
+                                                IPv6Address last)
+
+
+
+
+
+
+
+
+
+ +

+contains

+
+public boolean contains(IPv6Address address)
+
+
+
+
+
+
+
+
+
+ +

+contains

+
+public boolean contains(IPv6AddressRange range)
+
+
+
+
+
+
+
+
+
+ +

+overlaps

+
+public boolean overlaps(IPv6AddressRange range)
+
+
+
+
+
+
+
+
+
+ +

+iterator

+
+public Iterator<IPv6Address> iterator()
+
+
+
Specified by:
iterator in interface Iterable<IPv6Address>
+
+
+ +
Returns:
an iterator which iterates all addresses in this range, in order.
+
+
+
+ +

+remove

+
+public List<IPv6AddressRange> remove(IPv6Address address)
+
+
Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned. +

+

+
+
+
+
Parameters:
address - adddress to remove from the range +
Returns:
list of resulting ranges
+
+
+
+ +

+extend

+
+public IPv6AddressRange extend(IPv6Address address)
+
+
Extend the range just enough at its head or tail such that the given address is included. +

+

+
+
+
+
Parameters:
address - address to extend the range to +
Returns:
new (bigger) range
+
+
+
+ +

+remove

+
+public List<IPv6AddressRange> remove(IPv6Network network)
+
+
Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned. +

+

+
+
+
+
Parameters:
network - network to remove from the range +
Returns:
list of resulting ranges
+
+
+
+ +

+toString

+
+public String toString()
+
+
+
Overrides:
toString in class Object
+
+
+
+
+
+
+ +

+toLongString

+
+public String toLongString()
+
+
+
+
+
+ +
Returns:
like toString but without using shorthand notations for addresses
+
+
+
+ +

+compareTo

+
+public int compareTo(IPv6AddressRange that)
+
+
The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal. +

+ Note that the natural order does thus not compare sizes of ranges. +

+

+
Specified by:
compareTo in interface Comparable<IPv6AddressRange>
+
+
+
Parameters:
that - range to compare with +
Returns:
negative, zero or positive depending on whether this is smaller, equal or greater than that
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
+
Overrides:
equals in class Object
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
Overrides:
hashCode in class Object
+
+
+
+
+
+
+ +

+getFirst

+
+public IPv6Address getFirst()
+
+
+
+
+
+
+
+
+
+ +

+getLast

+
+public IPv6Address getLast()
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..dd7e2fa --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,399 @@ + + + + + + + +IPv6Network (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6Network

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6AddressRange
+      extended by com.googlecode.ipv6.IPv6Network
+
+
+
All Implemented Interfaces:
Comparable<IPv6AddressRange>, Iterable<IPv6Address>
+
+
+
+
public final class IPv6Network
extends IPv6AddressRange
+ + +

+Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks). +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleanequals(Object o) + +
+           
+static IPv6NetworkfromAddressAndMask(IPv6Address address, + IPv6NetworkMask networkMask) + +
+          Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+static IPv6NetworkfromString(String string) + +
+          Create an IPv6 network from its String representation.
+static IPv6NetworkfromTwoAddresses(IPv6Address one, + IPv6Address two) + +
+          Create an IPv6 network from the two addresses within the network.
+ IPv6NetworkMaskgetNetmask() + +
+           
+ inthashCode() + +
+           
+ StringtoLongString() + +
+           
+ StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class com.googlecode.ipv6.IPv6AddressRange
compareTo, contains, contains, extend, fromFirstAndLast, getFirst, getLast, iterator, overlaps, remove, remove
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+fromAddressAndMask

+
+public static IPv6Network fromAddressAndMask(IPv6Address address,
+                                             IPv6NetworkMask networkMask)
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask +

+

+
Parameters:
address - IPv6 address (the network address or any other address within the network)
networkMask - IPv6 network mask +
Returns:
IPv6 network
+
+
+
+ +

+fromTwoAddresses

+
+public static IPv6Network fromTwoAddresses(IPv6Address one,
+                                           IPv6Address two)
+
+
Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses. +

+

+
Parameters:
one - address one
two - address two, should be bigger than address one
+
+
+
+ +

+fromString

+
+public static IPv6Network fromString(String string)
+
+
Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". +

+

+
Parameters:
string - string representation +
Returns:
IPv6 network
+
+
+
+ +

+toString

+
+public String toString()
+
+
+
Overrides:
toString in class IPv6AddressRange
+
+
+
+
+
+
+ +

+toLongString

+
+public String toLongString()
+
+
+
Overrides:
toLongString in class IPv6AddressRange
+
+
+ +
Returns:
like toString but without using shorthand notations for addresses
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
+
Overrides:
equals in class IPv6AddressRange
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
Overrides:
hashCode in class IPv6AddressRange
+
+
+
+
+
+
+ +

+getNetmask

+
+public IPv6NetworkMask getNetmask()
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..5da8d81 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6NetworkHelpers

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6NetworkHelpers
+
+
+
+
public class IPv6NetworkHelpers
extends Object
+ + +

+Helper methods used by IPv6Network. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
IPv6NetworkHelpers() + +
+           
+  + + + + + + + +
+Method Summary
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+IPv6NetworkHelpers

+
+public IPv6NetworkHelpers()
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..d5b864f --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,358 @@ + + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.googlecode.ipv6 +
+Class IPv6NetworkMask

+
+java.lang.Object
+  extended by com.googlecode.ipv6.IPv6NetworkMask
+
+
+
+
public final class IPv6NetworkMask
extends Object
+ + +

+Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. +

+ +

+

+
Author:
+
Jan Van Besien
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ IPv6AddressasAddress() + +
+           
+ intasPrefixLength() + +
+           
+ booleanequals(Object o) + +
+           
+static IPv6NetworkMaskfromAddress(IPv6Address iPv6Address) + +
+          Construct an IPv6 network mask from an IPv6 address.
+static IPv6NetworkMaskfromPrefixLength(int prefixLength) + +
+          Construct an IPv6 network mask from a prefix length.
+ inthashCode() + +
+           
+ StringtoString() + +
+           
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+fromAddress

+
+public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
+
+
Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. +

+

+
Parameters:
iPv6Address - address to use as network mask +
Throws: +
IllegalArgumentException - if the address is not a valid network mask
+
+
+
+ +

+fromPrefixLength

+
+public static IPv6NetworkMask fromPrefixLength(int prefixLength)
+
+
Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. +

+

+
Parameters:
prefixLength - prefix length +
Throws: +
IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
+
+
+
+ +

+asPrefixLength

+
+public int asPrefixLength()
+
+
+
+
+
+
+ +

+asAddress

+
+public IPv6Address asAddress()
+
+
+
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
+
Overrides:
equals in class Object
+
+
+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
+
Overrides:
hashCode in class Object
+
+
+
+
+
+
+ +

+toString

+
+public String toString()
+
+
+
Overrides:
toString in class Object
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..b0b8f11 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,345 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6Address

+
+ + + + + +
+Uses of IPv6Address in com.googlecode.ipv6
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return IPv6Address
+ IPv6AddressIPv6Address.add(int value) + +
+          Addition.
+ IPv6AddressIPv6NetworkMask.asAddress() + +
+           
+static IPv6AddressIPv6Address.fromInetAddress(InetAddress inetAddress) + +
+          Create an IPv6 address from a java.net.Inet6Address.
+static IPv6AddressIPv6Address.fromString(String string) + +
+          Create an IPv6 address from its String representation.
+ IPv6AddressIPv6AddressRange.getFirst() + +
+           
+ IPv6AddressIPv6AddressPool.getFirst() + +
+           
+ IPv6AddressIPv6AddressRange.getLast() + +
+           
+ IPv6AddressIPv6AddressPool.getLast() + +
+           
+ IPv6AddressIPv6Address.maskWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Mask the address with the given network mask.
+ IPv6AddressIPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Calculate the maximum address with the given network mask.
+ IPv6AddressIPv6Address.subtract(int value) + +
+          Subtraction.
+  +

+ + + + + + + + + +
Methods in com.googlecode.ipv6 that return types with arguments of type IPv6Address
+ Iterator<IPv6Address>IPv6AddressRange.iterator() + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 with parameters of type IPv6Address
+ intIPv6Address.compareTo(IPv6Address that) + +
+           
+ booleanIPv6AddressRange.contains(IPv6Address address) + +
+           
+ booleanIPv6AddressPool.contains(IPv6Address address) + +
+           
+ IPv6AddressRangeIPv6AddressRange.extend(IPv6Address address) + +
+          Extend the range just enough at its head or tail such that the given address is included.
+static IPv6NetworkMaskIPv6NetworkMask.fromAddress(IPv6Address iPv6Address) + +
+          Construct an IPv6 network mask from an IPv6 address.
+static IPv6NetworkIPv6Network.fromAddressAndMask(IPv6Address address, + IPv6NetworkMask networkMask) + +
+          Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+static IPv6AddressRangeIPv6AddressRange.fromFirstAndLast(IPv6Address first, + IPv6Address last) + +
+           
+static IPv6NetworkIPv6Network.fromTwoAddresses(IPv6Address one, + IPv6Address two) + +
+          Create an IPv6 network from the two addresses within the network.
+ List<IPv6AddressRange>IPv6AddressRange.remove(IPv6Address address) + +
+          Remove an address from the range, resulting in one, none or two new ranges.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..54659ac --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,143 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+No usage of com.googlecode.ipv6.IPv6AddressHelpers +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..2b328fd --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,191 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+ + + + + +
+Uses of IPv6AddressPool in com.googlecode.ipv6
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return IPv6AddressPool
+ IPv6AddressPoolIPv6AddressPool.allocate() + +
+          Allocate the first available subnet from the pool.
+ IPv6AddressPoolIPv6AddressPool.allocate(IPv6Network toAllocate) + +
+          Allocate the given subnet from the pool.
+ IPv6AddressPoolIPv6AddressPool.deAllocate(IPv6Network toDeAllocate) + +
+          Give a network back to the pool (de-allocate).
+static IPv6AddressPoolIPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange range, + IPv6NetworkMask allocationSubnetSize) + +
+          Create a pool of the given range (boundaries inclusive) which is completely free.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..3f6841e --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,273 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+ + + + + +
+Uses of IPv6AddressRange in com.googlecode.ipv6
+  +

+ + + + + + + + + +
Subclasses of IPv6AddressRange in com.googlecode.ipv6
+ classIPv6Network + +
+          Immutable representation of an IPv6 network based on an address and a prefix length.
+  +

+ + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return IPv6AddressRange
+ IPv6AddressRangeIPv6AddressRange.extend(IPv6Address address) + +
+          Extend the range just enough at its head or tail such that the given address is included.
+static IPv6AddressRangeIPv6AddressRange.fromFirstAndLast(IPv6Address first, + IPv6Address last) + +
+           
+  +

+ + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return types with arguments of type IPv6AddressRange
+ List<IPv6AddressRange>IPv6AddressRange.remove(IPv6Address address) + +
+          Remove an address from the range, resulting in one, none or two new ranges.
+ List<IPv6AddressRange>IPv6AddressRange.remove(IPv6Network network) + +
+          Remove a network from the range, resulting in one, none or two new ranges.
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 with parameters of type IPv6AddressRange
+ intIPv6AddressRange.compareTo(IPv6AddressRange that) + +
+          The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal.
+ booleanIPv6AddressRange.contains(IPv6AddressRange range) + +
+           
+ booleanIPv6AddressPool.contains(IPv6AddressRange range) + +
+           
+static IPv6AddressPoolIPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange range, + IPv6NetworkMask allocationSubnetSize) + +
+          Create a pool of the given range (boundaries inclusive) which is completely free.
+ booleanIPv6AddressRange.overlaps(IPv6AddressRange range) + +
+           
+ booleanIPv6AddressPool.overlaps(IPv6AddressRange range) + +
+           
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..1d1ba28 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,248 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6Network

+
+ + + + + +
+Uses of IPv6Network in com.googlecode.ipv6
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return IPv6Network
+static IPv6NetworkIPv6Network.fromAddressAndMask(IPv6Address address, + IPv6NetworkMask networkMask) + +
+          Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+static IPv6NetworkIPv6Network.fromString(String string) + +
+          Create an IPv6 network from its String representation.
+static IPv6NetworkIPv6Network.fromTwoAddresses(IPv6Address one, + IPv6Address two) + +
+          Create an IPv6 network from the two addresses within the network.
+ IPv6NetworkIPv6AddressPool.getLastAllocated() + +
+           
+  +

+ + + + + + + + + +
Methods in com.googlecode.ipv6 that return types with arguments of type IPv6Network
+ Iterable<IPv6Network>IPv6AddressPool.freeNetworks() + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 with parameters of type IPv6Network
+ IPv6AddressPoolIPv6AddressPool.allocate(IPv6Network toAllocate) + +
+          Allocate the given subnet from the pool.
+ IPv6AddressPoolIPv6AddressPool.deAllocate(IPv6Network toDeAllocate) + +
+          Give a network back to the pool (de-allocate).
+ booleanIPv6AddressPool.isFree(IPv6Network network) + +
+           
+ List<IPv6AddressRange>IPv6AddressRange.remove(IPv6Network network) + +
+          Remove a network from the range, resulting in one, none or two new ranges.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..b82a77d --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,143 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+No usage of com.googlecode.ipv6.IPv6NetworkHelpers +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..3eb0c7f --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,224 @@ + + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+ + + + + +
+Uses of IPv6NetworkMask in com.googlecode.ipv6
+  +

+ + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 that return IPv6NetworkMask
+static IPv6NetworkMaskIPv6NetworkMask.fromAddress(IPv6Address iPv6Address) + +
+          Construct an IPv6 network mask from an IPv6 address.
+static IPv6NetworkMaskIPv6NetworkMask.fromPrefixLength(int prefixLength) + +
+          Construct an IPv6 network mask from a prefix length.
+ IPv6NetworkMaskIPv6Network.getNetmask() + +
+           
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in com.googlecode.ipv6 with parameters of type IPv6NetworkMask
+static IPv6NetworkIPv6Network.fromAddressAndMask(IPv6Address address, + IPv6NetworkMask networkMask) + +
+          Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+static IPv6AddressPoolIPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange range, + IPv6NetworkMask allocationSubnetSize) + +
+          Create a pool of the given range (boundaries inclusive) which is completely free.
+ IPv6AddressIPv6Address.maskWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Mask the address with the given network mask.
+ IPv6AddressIPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask networkMask) + +
+          Calculate the maximum address with the given network mask.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..f4ddab2 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,45 @@ + + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.8 API) + + + + + + + + + + + +com.googlecode.ipv6 + + + + +
+Classes  + +
+IPv6Address +
+IPv6AddressHelpers +
+IPv6AddressPool +
+IPv6AddressRange +
+IPv6Network +
+IPv6NetworkHelpers +
+IPv6NetworkMask
+ + + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..11ea3f5 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,180 @@ + + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package com.googlecode.ipv6 +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Class Summary
IPv6AddressImmutable representation of an IPv6 address.
IPv6AddressHelpersHelper methods used by IPv6Address.
IPv6AddressPoolImmutable representation of an IPv6 address pool.
IPv6AddressRangeImmutable representation of a continuous range of IPv6 addresses (bounds included).
IPv6NetworkImmutable representation of an IPv6 network based on an address and a prefix length.
IPv6NetworkHelpersHelper methods used by IPv6Network.
IPv6NetworkMaskImmutable representation of an IPv6 network mask.
+  + +

+

+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..aa61c6b --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,153 @@ + + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package com.googlecode.ipv6 +

+
+

+Class Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..c7fc4ef --- /dev/null +++ b/artifacts/0.8/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,180 @@ + + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
com.googlecode.ipv6

+
+ + + + + + + + + + + + + + + + + + + + +
+Classes in com.googlecode.ipv6 used by com.googlecode.ipv6
IPv6Address + +
+          Immutable representation of an IPv6 address.
IPv6AddressPool + +
+          Immutable representation of an IPv6 address pool.
IPv6AddressRange + +
+          Immutable representation of a continuous range of IPv6 addresses (bounds included).
IPv6Network + +
+          Immutable representation of an IPv6 network based on an address and a prefix length.
IPv6NetworkMask + +
+          Immutable representation of an IPv6 network mask.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/constant-values.html b/artifacts/0.8/doc/apidocs/constant-values.html new file mode 100644 index 0000000..ae4c386 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/constant-values.html @@ -0,0 +1,145 @@ + + + + + + + +Constant Field Values (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Constant Field Values

+
+
+Contents
    +
+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/deprecated-list.html b/artifacts/0.8/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..955ae94 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/deprecated-list.html @@ -0,0 +1,145 @@ + + + + + + + +Deprecated List (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Deprecated API

+
+
+Contents
    +
+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/help-doc.html b/artifacts/0.8/doc/apidocs/help-doc.html new file mode 100644 index 0000000..40bda50 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + + +API Help (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+How This API Document Is Organized

+
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.

+Package

+
+ +

+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:

    +
  • Interfaces (italic)
  • Classes
  • Enums
  • Exceptions
  • Errors
  • Annotation Types
+
+

+Class/Interface

+
+ +

+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
  • Class inheritance diagram
  • Direct Subclasses
  • All Known Subinterfaces
  • All Known Implementing Classes
  • Class/interface declaration
  • Class/interface description +

    +

  • Nested Class Summary
  • Field Summary
  • Constructor Summary
  • Method Summary +

    +

  • Field Detail
  • Constructor Detail
  • Method Detail
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+ +

+Annotation Type

+
+ +

+Each annotation type has its own separate page with the following sections:

    +
  • Annotation Type declaration
  • Annotation Type description
  • Required Element Summary
  • Optional Element Summary
  • Element Detail
+
+ +

+Enum

+
+ +

+Each enum has its own separate page with the following sections:

    +
  • Enum declaration
  • Enum description
  • Enum Constant Summary
  • Enum Constant Detail
+
+

+Use

+
+Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+

+Tree (Class Hierarchy)

+
+There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
    +
  • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
  • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+

+Deprecated API

+
+The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+

+Index

+
+The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+

+Prev/Next

+These links take you to the next or previous class, interface, package, or related page.

+Frames/No Frames

+These links show and hide the HTML frames. All pages are available with or without frames. +

+

+Serialized Form

+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description. +

+

+Constant Field Values

+The Constant Field Values page lists the static final fields and their values. +

+ + +This help file applies to API documentation generated using the standard doclet. + +
+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/index-all.html b/artifacts/0.8/doc/apidocs/index-all.html new file mode 100644 index 0000000..d51b3c3 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/index-all.html @@ -0,0 +1,417 @@ + + + + + + + +Index (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I M N O R S T
+

+A

+
+
add(int) - +Method in class com.googlecode.ipv6.IPv6Address +
Addition. +
allocate() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
Allocate the first available subnet from the pool. +
allocate(IPv6Network) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
Allocate the given subnet from the pool. +
asAddress() - +Method in class com.googlecode.ipv6.IPv6NetworkMask +
  +
asPrefixLength() - +Method in class com.googlecode.ipv6.IPv6NetworkMask +
  +
+
+

+C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
 
compareTo(IPv6Address) - +Method in class com.googlecode.ipv6.IPv6Address +
  +
compareTo(IPv6AddressRange) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal. +
contains(IPv6Address) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
contains(IPv6AddressRange) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
contains(IPv6Address) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
contains(IPv6AddressRange) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
countOccurrences(String, char) - +Static method in class com.googlecode.ipv6.IPv6AddressHelpers +
  +
+
+

+D

+
+
deAllocate(IPv6Network) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
Give a network back to the pool (de-allocate). +
+
+

+E

+
+
equals(Object) - +Method in class com.googlecode.ipv6.IPv6Address +
  +
equals(Object) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
equals(Object) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
equals(Object) - +Method in class com.googlecode.ipv6.IPv6Network +
  +
equals(Object) - +Method in class com.googlecode.ipv6.IPv6NetworkMask +
  +
extend(IPv6Address) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
Extend the range just enough at its head or tail such that the given address is included. +
+
+

+F

+
+
freeNetworks() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
fromAddress(IPv6Address) - +Static method in class com.googlecode.ipv6.IPv6NetworkMask +
Construct an IPv6 network mask from an IPv6 address. +
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - +Static method in class com.googlecode.ipv6.IPv6Network +
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask +
fromFirstAndLast(IPv6Address, IPv6Address) - +Static method in class com.googlecode.ipv6.IPv6AddressRange +
  +
fromInetAddress(InetAddress) - +Static method in class com.googlecode.ipv6.IPv6Address +
Create an IPv6 address from a java.net.Inet6Address. +
fromPrefixLength(int) - +Static method in class com.googlecode.ipv6.IPv6NetworkMask +
Construct an IPv6 network mask from a prefix length. +
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - +Static method in class com.googlecode.ipv6.IPv6AddressPool +
Create a pool of the given range (boundaries inclusive) which is completely free. +
fromString(String) - +Static method in class com.googlecode.ipv6.IPv6Address +
Create an IPv6 address from its String representation. +
fromString(String) - +Static method in class com.googlecode.ipv6.IPv6Network +
Create an IPv6 network from its String representation. +
fromTwoAddresses(IPv6Address, IPv6Address) - +Static method in class com.googlecode.ipv6.IPv6Network +
Create an IPv6 network from the two addresses within the network. +
+
+

+G

+
+
generateZeroes(int) - +Static method in class com.googlecode.ipv6.IPv6AddressHelpers +
  +
getFirst() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
getFirst() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
getHighBits() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
getLast() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
getLast() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
getLastAllocated() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
getLowBits() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
getNetmask() - +Method in class com.googlecode.ipv6.IPv6Network +
  +
+
+

+H

+
+
hashCode() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
hashCode() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
hashCode() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
hashCode() - +Method in class com.googlecode.ipv6.IPv6Network +
  +
hashCode() - +Method in class com.googlecode.ipv6.IPv6NetworkMask +
  +
+
+

+I

+
+
IPv6Address - Class in com.googlecode.ipv6
Immutable representation of an IPv6 address.
IPv6AddressHelpers - Class in com.googlecode.ipv6
Helper methods used by IPv6Address.
IPv6AddressHelpers() - +Constructor for class com.googlecode.ipv6.IPv6AddressHelpers +
  +
IPv6AddressPool - Class in com.googlecode.ipv6
Immutable representation of an IPv6 address pool.
IPv6AddressRange - Class in com.googlecode.ipv6
Immutable representation of a continuous range of IPv6 addresses (bounds included).
IPv6Network - Class in com.googlecode.ipv6
Immutable representation of an IPv6 network based on an address and a prefix length.
IPv6NetworkHelpers - Class in com.googlecode.ipv6
Helper methods used by IPv6Network.
IPv6NetworkHelpers() - +Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers +
  +
IPv6NetworkMask - Class in com.googlecode.ipv6
Immutable representation of an IPv6 network mask.
isExhausted() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
isFree(IPv6Network) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
iterator() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
+
+

+M

+
+
maskWithNetworkMask(IPv6NetworkMask) - +Method in class com.googlecode.ipv6.IPv6Address +
Mask the address with the given network mask. +
maximumAddressWithNetworkMask(IPv6NetworkMask) - +Method in class com.googlecode.ipv6.IPv6Address +
Calculate the maximum address with the given network mask. +
+
+

+N

+
+
numberOfLeadingOnes() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
numberOfLeadingZeroes() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
numberOfTrailingOnes() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
numberOfTrailingZeroes() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
+
+

+O

+
+
overlaps(IPv6AddressRange) - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
overlaps(IPv6AddressRange) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
+
+

+R

+
+
remove(IPv6Address) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
Remove an address from the range, resulting in one, none or two new ranges. +
remove(IPv6Network) - +Method in class com.googlecode.ipv6.IPv6AddressRange +
Remove a network from the range, resulting in one, none or two new ranges. +
+
+

+S

+
+
subtract(int) - +Method in class com.googlecode.ipv6.IPv6Address +
Subtraction. +
+
+

+T

+
+
toInetAddress() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
toLongString() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
toLongString() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
toLongString() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
toLongString() - +Method in class com.googlecode.ipv6.IPv6Network +
  +
toShortArray() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
toString() - +Method in class com.googlecode.ipv6.IPv6Address +
  +
toString() - +Method in class com.googlecode.ipv6.IPv6AddressPool +
  +
toString() - +Method in class com.googlecode.ipv6.IPv6AddressRange +
  +
toString() - +Method in class com.googlecode.ipv6.IPv6Network +
  +
toString() - +Method in class com.googlecode.ipv6.IPv6NetworkMask +
  +
+
+A C D E F G H I M N O R S T + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/index.html b/artifacts/0.8/doc/apidocs/index.html new file mode 100644 index 0000000..1e9bc16 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/index.html @@ -0,0 +1,37 @@ + + + + + + + +Java IPv6 Library 0.8 API + + + + + + + + +<H2> +Frame Alert</H2> + +<P> +This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. +<BR> +Link to<A HREF="com/googlecode/ipv6/package-summary.html">Non-frame version.</A> + + + diff --git a/artifacts/0.8/doc/apidocs/overview-tree.html b/artifacts/0.8/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..b858149 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/overview-tree.html @@ -0,0 +1,155 @@ + + + + + + + +Class Hierarchy (Java IPv6 Library 0.8 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For All Packages

+
+
+
Package Hierarchies:
com.googlecode.ipv6
+
+

+Class Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2012. All Rights Reserved. + + diff --git a/artifacts/0.8/doc/apidocs/package-list b/artifacts/0.8/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.8/doc/apidocs/resources/inherit.gif b/artifacts/0.8/doc/apidocs/resources/inherit.gif new file mode 100644 index 0000000000000000000000000000000000000000..c814867a13deb0ca7ea2156c6ca1d5a03372af7e GIT binary patch literal 57 zcmZ?wbhEHbIIT!9-C*e{wE9>Kx3D)-;0v)C; KYxQGgum%9JOA&7X literal 0 HcmV?d00001 diff --git a/artifacts/0.8/doc/apidocs/stylesheet.css b/artifacts/0.8/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..6ea9e51 --- /dev/null +++ b/artifacts/0.8/doc/apidocs/stylesheet.css @@ -0,0 +1,29 @@ +/* Javadoc style sheet */ + +/* Define colors, fonts and other style attributes here to override the defaults */ + +/* Page background color */ +body { background-color: #FFFFFF; color:#000000 } + +/* Headings */ +h1 { font-size: 145% } + +/* Table colors */ +.TableHeadingColor { background: #CCCCFF; color:#000000 } /* Dark mauve */ +.TableSubHeadingColor { background: #EEEEFF; color:#000000 } /* Light mauve */ +.TableRowColor { background: #FFFFFF; color:#000000 } /* White */ + +/* Font used in left-hand frame lists */ +.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif; color:#000000 } +.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 } +.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 } + +/* Navigation bar fonts and colors */ +.NavBarCell1 { background-color:#EEEEFF; color:#000000} /* Light mauve */ +.NavBarCell1Rev { background-color:#00008B; color:#FFFFFF} /* Dark Blue */ +.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;color:#000000;} +.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;color:#FFFFFF;} + +.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000} +.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000} + diff --git a/artifacts/0.9/doc/apidocs/allclasses-frame.html b/artifacts/0.9/doc/apidocs/allclasses-frame.html new file mode 100644 index 0000000..a0f66be --- /dev/null +++ b/artifacts/0.9/doc/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.9 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.9/doc/apidocs/allclasses-noframe.html b/artifacts/0.9/doc/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..ffdd7ab --- /dev/null +++ b/artifacts/0.9/doc/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +All Classes (Java IPv6 Library 0.9 API) + + + + +

All Classes

+ + + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6Address.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..dcc4c9f --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,515 @@ + + + + + + +IPv6Address (Java IPv6 Library 0.9 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        Parameters:
        inetAddress - Inet6Address representation
        +
        Returns:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        Parameters:
        value - value to add
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        Parameters:
        value - value to substract
        +
        Returns:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        Parameters:
        networkMask - network mask
        +
        Returns:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        +
        Overrides:
        +
        toString in class Object
        +
        Returns:
        String representation of the IPv6 address, using shorthand notation whenever possible.
        +
      • +
      + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        String representation of the IPv6 address, never using shorthand notation.
        +
      • +
      + + + +
        +
      • +

        toShortArray

        +
        public short[] toShortArray()
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..90a4087 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.9 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..e763566 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,474 @@ + + + + + + +IPv6AddressPool (Java IPv6 Library 0.9 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromRangeAndSubnet

        +
        public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
        +                                 IPv6NetworkMask allocationSubnetSize)
        +
        Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size).
        +
        Parameters:
        range - range from within to allocate
        allocationSubnetSize - size of the subnets that will be allocated
        +
      • +
      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        Returns:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        Parameters:
        toAllocate - subnet to allocate from the pool
        +
        Returns:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        Parameters:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        Returns:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        Returns:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..06b8dc0 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,467 @@ + + + + + + +IPv6AddressRange (Java IPv6 Library 0.9 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + + + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        Parameters:
        address - adddress to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        Parameters:
        address - address to extend the range to
        +
        Returns:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        Parameters:
        network - network to remove from the range
        +
        Returns:
        list of resulting ranges
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + +
        +
      • +

        compareTo

        +
        public int compareTo(IPv6AddressRange that)
        +
        The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal. +

        + Note that the natural order does thus not compare sizes of ranges.

        +
        +
        Specified by:
        +
        compareTo in interface Comparable<IPv6AddressRange>
        +
        Parameters:
        that - range to compare with
        +
        Returns:
        negative, zero or positive depending on whether this is smaller, equal or greater than that
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6Network.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..c066760 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,368 @@ + + + + + + +IPv6Network (Java IPv6 Library 0.9 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6Network

+
+
+ +
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddressAndMask

        +
        public static IPv6Network fromAddressAndMask(IPv6Address address,
        +                             IPv6NetworkMask networkMask)
        +
        Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
        +
        Parameters:
        address - IPv6 address (the network address or any other address within the network)
        networkMask - IPv6 network mask
        +
        Returns:
        IPv6 network
        +
      • +
      + + + +
        +
      • +

        fromTwoAddresses

        +
        public static IPv6Network fromTwoAddresses(IPv6Address one,
        +                           IPv6Address two)
        +
        Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses.
        +
        Parameters:
        one - address one
        two - address two, should be bigger than address one
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        Parameters:
        string - string representation
        +
        Returns:
        IPv6 network
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        +
        Overrides:
        +
        toLongString in class IPv6AddressRange
        +
        Returns:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..81dc559 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.9 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..df04da9 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,328 @@ + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.9 API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

Class IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    Author:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        fromAddress

        +
        public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        Parameters:
        iPv6Address - address to use as network mask
        +
        Throws:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        fromPrefixLength

        +
        public static IPv6NetworkMask fromPrefixLength(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        Parameters:
        prefixLength - prefix length
        +
        Throws:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      + + + +
        +
      • +

        asPrefixLength

        +
        public int asPrefixLength()
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        Overrides:
        +
        equals in class Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        Overrides:
        +
        hashCode in class Object
        +
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..16cc059 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,263 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Address (Java IPv6 Library 0.9 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Address

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..70ca9d3 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressHelpers (Java IPv6 Library 0.9 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressHelpers

+
+
No usage of com.googlecode.ipv6.IPv6AddressHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..b5f2ff1 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,161 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressPool (Java IPv6 Library 0.9 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressPool

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..ca3cbdb --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,222 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6AddressRange (Java IPv6 Library 0.9 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6AddressRange

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..63cceef --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,204 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6Network (Java IPv6 Library 0.9 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6Network

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..bb74f17 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkHelpers (Java IPv6 Library 0.9 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkHelpers

+
+
No usage of com.googlecode.ipv6.IPv6NetworkHelpers
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..b714a1c --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,187 @@ + + + + + + +Uses of Class com.googlecode.ipv6.IPv6NetworkMask (Java IPv6 Library 0.9 API) + + + + + + + + + + +
+

Uses of Class
com.googlecode.ipv6.IPv6NetworkMask

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-frame.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..5121c54 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.9 API) + + + + +

com.googlecode.ipv6

+ + + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-summary.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..53c5551 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.9 API) + + + + + + + + + + +
+

Package com.googlecode.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary 
    ClassDescription
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-tree.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..f8766a9 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +com.googlecode.ipv6 Class Hierarchy (Java IPv6 Library 0.9 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For Package com.googlecode.ipv6

+
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-use.html b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..a2766d1 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +Uses of Package com.googlecode.ipv6 (Java IPv6 Library 0.9 API) + + + + + + + +
+ + + + + +
+ + +
+

Uses of Package
com.googlecode.ipv6

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/constant-values.html b/artifacts/0.9/doc/apidocs/constant-values.html new file mode 100644 index 0000000..6d70982 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +Constant Field Values (Java IPv6 Library 0.9 API) + + + + + + + +
+ + + + + +
+ + +
+

Constant Field Values

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/deprecated-list.html b/artifacts/0.9/doc/apidocs/deprecated-list.html new file mode 100644 index 0000000..83f97c7 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +Deprecated List (Java IPv6 Library 0.9 API) + + + + + + + +
+ + + + + +
+ + +
+

Deprecated API

+

Contents

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/help-doc.html b/artifacts/0.9/doc/apidocs/help-doc.html new file mode 100644 index 0000000..026f0af --- /dev/null +++ b/artifacts/0.9/doc/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API Help (Java IPv6 Library 0.9 API) + + + + + + + +
+ + + + + +
+ + +
+

How This API Document Is Organized

+
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
    +
  • +

    Package

    +

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    +
      +
    • Interfaces (italic)
    • +
    • Classes
    • +
    • Enums
    • +
    • Exceptions
    • +
    • Errors
    • +
    • Annotation Types
    • +
    +
  • +
  • +

    Class/Interface

    +

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    +
      +
    • Class inheritance diagram
    • +
    • Direct Subclasses
    • +
    • All Known Subinterfaces
    • +
    • All Known Implementing Classes
    • +
    • Class/interface declaration
    • +
    • Class/interface description
    • +
    +
      +
    • Nested Class Summary
    • +
    • Field Summary
    • +
    • Constructor Summary
    • +
    • Method Summary
    • +
    +
      +
    • Field Detail
    • +
    • Constructor Detail
    • +
    • Method Detail
    • +
    +

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

    +
  • +
  • +

    Annotation Type

    +

    Each annotation type has its own separate page with the following sections:

    +
      +
    • Annotation Type declaration
    • +
    • Annotation Type description
    • +
    • Required Element Summary
    • +
    • Optional Element Summary
    • +
    • Element Detail
    • +
    +
  • +
  • +

    Enum

    +

    Each enum has its own separate page with the following sections:

    +
      +
    • Enum declaration
    • +
    • Enum description
    • +
    • Enum Constant Summary
    • +
    • Enum Constant Detail
    • +
    +
  • +
  • +

    Use

    +

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

    +
  • +
  • +

    Tree (Class Hierarchy)

    +

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    +
      +
    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • +
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
    • +
    +
  • +
  • +

    Deprecated API

    +

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

    +
  • +
  • +

    Index

    +

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

    +
  • +
  • +

    Prev/Next

    +

    These links take you to the next or previous class, interface, package, or related page.

    +
  • +
  • +

    Frames/No Frames

    +

    These links show and hide the HTML frames. All pages are available with or without frames.

    +
  • +
  • +

    All Classes

    +

    The All Classes link shows all classes and interfaces except non-static nested types.

    +
  • +
  • +

    Serialized Form

    +

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

    +
  • +
  • +

    Constant Field Values

    +

    The Constant Field Values page lists the static final fields and their values.

    +
  • +
+This help file applies to API documentation generated using the standard doclet.
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/index-all.html b/artifacts/0.9/doc/apidocs/index-all.html new file mode 100644 index 0000000..512e27b --- /dev/null +++ b/artifacts/0.9/doc/apidocs/index-all.html @@ -0,0 +1,405 @@ + + + + + + +Index (Java IPv6 Library 0.9 API) + + + + + + + +
+ + + + + +
+ + +
A C D E F G H I M N O R S T  + + +

A

+
+
add(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

C

+
+
com.googlecode.ipv6 - package com.googlecode.ipv6
+
 
+
compareTo(IPv6Address) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal.
+
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
equals(Object) - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
fromAddress(IPv6Address) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+
+
fromFirstAndLast(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
fromInetAddress(InetAddress) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromPrefixLength(int) - Static method in class com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - Static method in class com.googlecode.ipv6.IPv6AddressPool
+
+
Create a pool of the given range (boundaries inclusive) which is completely free.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
fromTwoAddresses(IPv6Address, IPv6Address) - Static method in class com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from the two addresses within the network.
+
+
+ + + +

G

+
+
generateZeroes(int) - Static method in class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getFirst() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getHighBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLast() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLowBits() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
getNetmask() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
hashCode() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - Constructor for class com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressRange - Class in com.googlecode.ipv6
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6Network - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6NetworkHelpers - Class in com.googlecode.ipv6
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - Constructor for class com.googlecode.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - Class in com.googlecode.ipv6
+
+
Immutable representation of an IPv6 network mask.
+
+
isExhausted() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
iterator() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
+ + + +

N

+
+
numberOfLeadingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - Method in class com.googlecode.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
subtract(int) - Method in class com.googlecode.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toInetAddress() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toLongString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toShortArray() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Address
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressPool
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6AddressRange
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6Network
+
 
+
toString() - Method in class com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+A C D E F G H I M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/index.html b/artifacts/0.9/doc/apidocs/index.html new file mode 100644 index 0000000..b280805 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/index.html @@ -0,0 +1,31 @@ + + + + + + +Java IPv6 Library 0.9 API + + + + + + +<noscript> +<div>JavaScript is disabled on your browser.</div> +</noscript> +<h2>Frame Alert</h2> +<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="com/googlecode/ipv6/package-summary.html">Non-frame version</a>.</p> + + + diff --git a/artifacts/0.9/doc/apidocs/overview-tree.html b/artifacts/0.9/doc/apidocs/overview-tree.html new file mode 100644 index 0000000..c5272a8 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +Class Hierarchy (Java IPv6 Library 0.9 API) + + + + + + + +
+ + + + + +
+ + +
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/artifacts/0.9/doc/apidocs/package-list b/artifacts/0.9/doc/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/artifacts/0.9/doc/apidocs/resources/background.gif b/artifacts/0.9/doc/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 zX3B0NWXQ443Eo1rUP86rLU>O>oTp%wt3Z{Tz&P*)Iraq^_@X;RtUFY!JxH|4U!>kw zxXwqo&R3Y=EsXaR!ng@y+y$%L1P3FZ4@N!j3m5MW74HcC->_JFuvlxLXiI=-OQ2|@ zpGc#>2-aN)<1RE9^`bB0`65VSK2>5m>CHs^YZCC)NX*NfbeT1%)Cxpu2_(6cCbLvjLY`hf1%*q}QO*%V4SfOu5Nqg~`-+(-76= za<`RA&(qDB^S!nIS^od5|Nk$KPXD8(qSB!f`M*{E?A^&yOW$08V^iNPK!%UNJ-@xmz>`pG2_%4I3QWk4UdtwP!GH$C%mo2K|$Ap=_)Y!#O($1@ohsUtR1k%wI*) z4*X&g==oWh`j{uP=HFm;Ye>0>UbDdtSp^~MaQ!L9I#)Ga?q}{@T#|qec*FkMLDenm zj^sCgk!^O^3o|vG!~2$$$7`C#4Ry zdQ!tui+J1*HyavK+4{`r+zvYHj9IsRt~@uEBOreWS8~2rXAR3!|7aTdr+x4|>@$Az z)b1t$gSB~6USxpfLmy^|_J_eNt*PI=ScO1SVH895N#`ef%IOh&o-2GIjK1s-JzkyZ z@r7O%hChz}kMHCM@Wqi^R-9t&%Fh^#9dVB0%ej@$=OjXA%XZdzCXf}c>SW26_z-Te z5b{}XWg&rELM=N*%aimp)k04t2c+`WAS>ZFIPWKvtyOI))HzpRA!T!b{tv?4NzF1v zNlP%#{&p@lFFEKvcroMAsI)mq?&`!e%l+-y&j9ZqhN}oG&dB=Pw09r+Q%m0cMujS# zs$a7!9VH`CC7k{!bV(J`rm%Jpj6&nLtWhPcy$onn$8G#ZdD9hxO<9k67Ya>K_7W~3 z&KYf14fq<{qHA7u6;>AOcomhdg?ianjr9uINt}*7w?g%z9{Q`(qRo@hDwSpGmxz&h&>%G%T(URL~=c>C{>y$K?+wLFp zy*M1@FTUKYV>8DeDIAIKM+!T5c-k&C4?Y~y^E zQCIc-=9~DiPtfVZB=_c3`qH3h|NXd^BcOQG`funSe)i5!NoA_r{b6PwzSDIXG+!(F z9CqJgo&~#7^VZHWj{u23q+NDCHn}GeWDC*(SW%{f4WMtP3l2jsO7*M)EX)#NLlsNnU4q@#jn0r#rsWsf^ngE0&ambG1f;Rj zfOk#_>1|25Z%?iI{0Yv8)DQfk>m1td?~}m0N%^k^u%EuUCc#ItmlY|epQ3YLWehYw zRU0qpPb#X&WU*UOU8et(s8x~WyYWYsgJCF+;U6@*nICY8)dk}IG+(#_Bz8zURd3HZ6qPE68U1%S{wL0 z;K{PDw2iRFIGG?(UiE9kT9?siuv4O{ z`dX2-eiXU3N)H2nT4V=AO^~J}sw+gr{&~qx%$$wlMv_JCWAMfcjYl}*Cfcf!adOY8 z8oLmJ{%49e+nLiVo#H9}wRk?UCzDz^>9TDxreVHzl~R*)?YU>Uu;J2eQ27O5`&X^8 z`94{)YWJQa#l0Fbz0N6B>j&8J;<%VuG6OYM9&QIdtueWjI3X;*dEtGiF@1AcvN4U> zG5SXIEXxB>)!mtQOztJLyeF78S*kLiU-!>PtQ_s~OMl~&y(hVVe$A5 zwo}E-DJ6${QP75?LsQ}Wl@MXwXMT4d>|?rD!g?jE>J^N*y;X}5FLe%d0_ zZ>eIBK6l@jkfw{p_YiDP;MS{jww{%j#?rk2z1J!HqE;Vd!TrCl_7UPef8;edI}wD6 zT&12Bxj&q}d4%$GHq+$~UYtWv`wI9k`89oKkCEK_E;-+O)(rhThjOM|kXDn{!W1Lo z`_?yQv=lp=-w()R<=0&c5%RWHY_fw@qb}uwFuPAGkl~@Kis}eE%MY@~6ZyWcF+llM zGyK`)(vn1F%%z=W7-Y=1$`w0Mv+-|#d};%JjCmw)Y1hOxwA|{}P%6LS4X`jQCGh`mR@=hGrr|cXa^Ipj;Mh)6mTqd1s_HmP0IxXT!w7YhoIHT>Hm#!;c@|L9OjV zsTlHE{Z;HWeM9^tPm-`|&nnl$%DRtNG1~?npUvgKPwKlaccEe4q!7YU3zykJnu6Sr z()LMXs_)^~u-ds7+wMff)RAJF?2?1H`_wDnt%MssYeB5;q~ojgVm6OHA6B>FG2erv z8&`|6<`=!EPKR^8Qlp5MiKwfxy4D`mN> ze$RKh_6*YJd4y0nnUZvwN%iY&^9xk@cM|5g#pZkc#N*(PH?^w&?ilTDMXFcd0`5!E zvgHS`=Lc|~1aO=L@L~eE*aP{90lc7qXY7GOs)3JH14T{(`K1D%tpvUT1-?F^1d4_S zJ#7yXkP3Q37bJlRQfv=mV-J3B8O*m5B%L3uW)S>|Jwy`|s6iK`sv0Z-3NcU(0knrG z5ChFXA@A9PUSdLI+(VU!!J1Mbw!~0VP^jZci2X|Nx0BF!24ObrAr>b=QtlyN4TAhn z!mQncJm~^m4MIafVLt_ewDUtO+e5w*!`(6A&H^F7i9s4t5&uBpNvh$nlTZjqTM5krNRRQ zqP)VR!|9@H>7qN_!+-)&_9s!^;gOvy5s~iEB&qP8{77&2NJMzZcsnJgSt_bYDzYU% zxQ#uuk3D*e7_*d5^?HW(^(WxICGf-mcmM((VStzIz%zFsm0;ZI3h=5OciJ#a%7I(IeGbFv+PP^?^sKBPrRBl<+qK^o%3fi=L9`la>-l4~p|hzAl~W zf=%(|NHgF7r5dJD+Cf08q-c(m;Epsldaz4cqHzTHT>)4xEe(cE0i~tf{Y0xs_1~Kv z+BYQ-TpEOch13;5YC9nHYEXhSv{ew=LV~nQL%UBQEgaDL2m?9u~v zEQmOvM=aB)Z$+eE38rs%AZR_)4>@2raqwH#Fji#xoLc&PS_TU^W8W(M0GqLdO~1yF z{sfHZ_sC#FX58(}d>RSkKZCz8%D7{cC3Z$Zh@52{31&V*W-@s~Z<8~aBeNcNW?e&O zsR(7fHOf}B&fsRqdZ(WK1e~s*o^uD6{YX9QJvqyWAqQXt*E>r$V94YK=X@8+{1cg> z*_i`a%alCJvbD~lCg&Q1Gk=|BzY)sejf9EHJ{s7lu4?ExCWR3jgTiET;exy{sW!Mg zuj*_YOf0@ScN~X0$7V6&KpL172rf|rA8?K<2+GelXw)NUk#@b4aT5MO%1ip4*ym}B-JI__S1R?CK z<4eW~bH;@H@tR55x}&JNSw_NvEPk)6E>XDt7*)4sgWuw+_vNZzmaS(tsi(57zcjA9 z@~XcHtzYq~IX|z*Md9mh>W~`sk3<^s7;EmyH4wcTdAo5NkUA2ofeG69{Gx7#i_*lt zQ7;N@xEo#nNRj&SbDHNnP0w#OE0{DZ$~7ySG%IN~zwd5Vu4&dnH>*OMb>&*VL^tbA zG;7y1t9dsYU$p3pw0x6mwGe6fjBYWsZ8e3q8f~-~cefgHxBangajI$kv(c*W-DZGp zbM$UgnP{_MYPXYX|6$u^deIhE(-xuGX2RVXqS+o~(iSV%;ZW1=Zqkut(r&xak^pT> zsp*I@X|-eOd^gb+sM(%3(E$|c47Y91mTU99Xe;4vFOTl5gmwVB+fvc3n2pwK?~Xd# zwrY{?CUj@~Msr?wXU0WKv2A$hq z`$V^gNq4(<*C=;4e4}$*uIC$5&uUHkM08J~N$>VV*VpdmLCuc!?!J9=-)VH;fo9)| zNN4m#^Kb9|`RF!^ZAT-z=bC8$do8~Tjc^o-aQjyc2(TW*d50E1#NW0pKb^~tf&OUlS+W}>0!m@!~1 z&TdSLhm`0u99c-z=oxYL8IFaGCDoFwFUP!1iJ%xF1UC4hhv*VR2451Pc0+kQGC)39C5 za81oV=$+xzZNYhn=RB-CTZ>Bevj)A3mi9|OS(dcy=N#Zm=Dza|z4Jd<=3IQ2CB>FiwH7{4Ej#+oa>M67 z!56)Km&2xJ|H7B;%~rJDuJ{rbZQiaX*e^$DEt~T$#h9(y#jg6>uX?boq!N}Q;EQth zYo1rjc15dETPw~*Ymu=lreoE9g^wb)ZcRe1yp1(Eo(rmqUYZXOU$BC_| zX{{&qE?E06wXm#v#cpKwE)jaydSaI`TkCCClr_lKMzPkyFT!R%VRn&sZSrchKx&4e~pJQcfViQxxl=T=7}#gYz7Pvoh`T#Jbab%2A2m zxh?A<`}A?8_GumBEcL;$x%gQb@PZ(If%ZE~D?ax#Km4a~+GV~!;Bb~qxxh@HHc|H6 zr%$^c9Dw~UQFWJv+81rCXS1vqqLfQ~-BtO63xCArGVA4T-}xPXYGHqB5h^+n5%$24 z(BROpi13J@*qFfR$oRMHel`=(zy zovs-UKHD3VkJ?hVeq!aA+8Fh4+NIlFhcC~UrR{4I#}K*u&z%68+P1*=q0B1r*2MY> z!9gYs*vlTO5v#8S>c#3goFmp>3iVKdU)NkjNV(s7tO4Wq?2M}o5Cj-*7;S=fEshOA zR*4$dm{ROvUamG%xL_tSW6}U$Nl=@91T;nC11o-iIVyVrfkd) zTCp;^tOy|_kuOFV$Nn=$AQJO9;&sZ&eDs^!r*m;Hw!)vpO1vcfj2EV{dJ?7ap0tq6 z$SwUVM*Vt+MS_`;bas-svPV|3POQi8G~?f^KOx4hg1He+Wd*s3Hl1{TfJS-+zv6vc zPoKiwr?7wECbub(IdB)9f_!kmUjBR*KY_z4E8_QA9xSr#G&@i5y^H`jB^I{|akh>W z%Cn3luOVY|8P>u>e^~#{$kmgX&-q>k{#pFbm2({(rtG<%nb0UCQ0%{Cy`F&~7}*we z@Of>ND_)V&XwN_+n~KjVorUQWZ*B6cld7ymQl{;rwlHl34K#}2YWxE+4CX@P&u6AfCda`&ZT1MOY69e-L@gNcAvwx8%1Z7lB4zc=_Cpt~&s ze%?;){1DB(PSK!^za967qF?lIjB~&06}Lf`cgh2qUiI^|$-VCTNE=hp&Ij}^A9&|* zQQrSqo3gn#_=z9j(y6f@T|OkJYv(fjwpz}$*U$|nLH2F zPNMuTS4g8 z*^hOlRh6~Mk}58;d477R>F^~aLO$dOXmhA*6zwIaHK()t2zKjo?j^NOJbh_=+71xg zO{Mgp7x?Z-1MKzoQ<+V2g#|e}|JawOPJZBL{o~PYdtWDX?jl##!Aiq|w>)vGJLipp zBK1xGhcvgSsQ;rn>+`>UmxlID{<~}7{y>SO^cyktN^Fsz!Z|B4?p*RKQG*8}SYBt{ zuFO{vJ?jgL{gUzYsnv(io}c0vlCp#*1vE?}KL^UZ&VF^TK+D;40CxX%j);%dCt;Z{ zAeMXC9JPWvKGwsCxx4w2iv_wNGG8l16AVI93rmc^c1>r(P||YE zpXa+=-&k995hfykL^J5S&vJF^ljR&`FE#ppNMM3%Omc!F)Mn{{&Ip#)JegbEJxud2 zn`wDVB~DMii5|H%m~51YeU1juNG3!+&?*uC#q@)z8q~`4yEL5I8}PtyA1IZ=52P$x zX)KhZt z7czUXBsy-8d`GVQ`90`wIh(Xt7v5j7h0t&ET~2M!Tb~4rN-xtK@8@mB*c(6QTwOS- z%9445_WY|cfm4?$nX$72&{~^mu}an^x^Da%=UU6YI;ur3+9L6I>raW5!=-Nzy(F2Z zwZlg7aM3NN5b{K|FB>s4R}|&Lr32_Ys{wwkECxo|rV@;5aHB25iUs7(6@dDpjN{Y%?C~UGp>*Q}K?)KKk64 zAn;@-dER}QG0L${jQ1cR75eM3-~ZTltTQ8%sm9x4Y`ve@ekMuvpA#Rh51@s6;6^&Q z!&M7^b%cea7FlZkPV9}@!bPBBfB&~XvGlE2T7V?IpM~OBmuK;OSt{~N`rL5c_I^de z9n*=@p|l;d`b_YIn8Aem1t7pp0=2-MCTIcJHlY z6x+mNLgi{JpwP)y(yzAFL2A#>bI&EwZE`PGvd*FQ!rx~6bUN&+Ij3)L;=595L#G;m8*^e?ap1`J5w7-q)*iUT_W9w8 z&xS-`i++HpWzY-a-)CWd0(pLW$A85P{Dy9r-=uPekNpN^yA}pJ7yWTZ>3iw4d6+IK zF%1XXkGcJm{0*vhSG5R1ySW;jctk9O==1-Mk?=Bl<{HE1p_@tx1s^+GoczYxj#B=i=kwQvEPrOt`<4W*pJw zbNjEqpr7B|Llc%m{V*QssV)im;pb00LUob=yFaU4`P_}ywU zt*QZl-bUsmh@L&zQaX4uHL&7YD(BOb9hH;;y;O-b-_O$4EFi1vCrMlz`dN|u?}HNO^aFQV{UZg_yy%nf>IXpulip!cR8|vNu7P*; zQye@}Qmj%(TB6`5E=c~w=LITF266XJ6X5xA7!OM1SE=~N*o3EP5Qqx!W<_+EMSLGo zqkC18AQ=0AK9=hgGQtrTovYc5^?Z^RLX?hlO-j&e1MXTTbfm>MS^=}!p>C>icUKdZ zBcNOb(6IJ!kq*e7N8Fx!!kPyn+2B2^2hd00+W^PUA&+S63jFE)bP5Tv+L5l~n(pu? zbeO|+K{{?pEow3?j0+dGVu)a6(0r{1Uj7{3 zxSsZ|BdMk>1-S}-;+`pk{Q5>H=tLRx+YqeenaSRsEX@gtPzz>j1A9g!C9kGtspY(- z%YL>NkVDE2z@}*;Q{=&5)yS;NupAmmibGUE4qte7aY6PcnXJgw>}ad(SW;@HtNurF ziV0_yHz=;Di%Tki6DW^tjkL`t%Ktct(ay zvuAOYoCu!Pm~@P5CIjk$bp`_iv{^l*Au{fB8mJK1>Macv?GL)**8*+JNvySIH5Y7i#1;!%NT!efc z;Z0*AOM&1VpR+6wIQxBM{xf`8T1V@#e<#QL}=YRwMkWG8%1(Fgj{iX)N zup{Txko(DqJWf=#Oi?Z!nra-?C{);TP`w|4>L+EKx1&P3swX<*#_50F!lD_$nQyuK??!UwA-{y)^QmMxoK1xIJ~uML{u;5!Z5tQyEL>;KaUd!_9FP zl2$QOI6V1`QdF|8gkdZsSpUqCjSBu(1H)r*vL#PEy)@Px>5TIk7_9o#Bj zzD&<1_k(ejk%qO6ak=GMmG5b7LTAA^KKq-Ey#z8(2wy2;Ot^oZI(MG@)~iY$RAnJt zu`ioyvR?Vws_tuK9hDqmel+)bP0kyxJV{7t=&3{b(@Hs1fs$9n45aq)IKknZa2H*7 z^P-ZDyOMdMj&-9{(-?dqo5I3Gy=K$!L%q>3^0N~o^2i0^_@^2nQv>S4B&=5_8^a^V zaY!NjyA5QgO&r#^CJcp&=!))MZ*CC&hvLEzWU*!IO=aYo{_yG+53H$XOAIQWnG`uD zLuuwTY6e8N^m5^AHQa}Y5Z#SdbEY;+x{oW?g;ie4CNYomRyQd2mv^L}T!>a5<*wTh>@>Qtwp~nejn`~DcZJI+QC-xU zoxz=5z0k%1;jBrGI%Th~FQElrAPr?E-Fv9|o09dPk=?>f)jFKL8PK|;w(cVDq>YWP zEfL7RGBv|<>f4IccND3wCi*V8`>#a$FPZu&a{V`W`me+Kuf_CJ)%IV%?5ByL^#3Q{ z&uBM5|34IKI>0_Tz{5OngXe#6w*N6;;5PH%9n%56%RaWA{wJ4%515Apdj`a62bp<> zM12OuV+QZ^55ATkViO(UWgg}%9C}kb^r~=BiDyWIXZWM&kb>Q?dd$#W`4KU|2#4qh zz;sZ>ZqS5h#Kdk$&1c9AHmDUdtmHE)CqH0RIAZEE;t(^+RXF+*FlJyk;?6Vn{&MsO zZ0HwY)b4Va!F1#s^N5$-s9(&mPa*Lu4>4SxXm~l|3?PR2jB1J!Q|(4#0i$lFME^-r zA~Q(2O+PHOdcVN((R8zqi>%+yx4PA5u&+jI zZ?)Fm8m-+`n!Bnrx0PvZE7!Q)Z+NTE@K(R!nO40sZF(n~bq_b_9H`UYU#q>pPJ3UC z_UeU>J7qcy%%`ks9)BNcS^GDOn z?oKkjHNoWO1e2?M#vd12e^_AscAnLnc~-CISiYWX`D%{k^H~<37unpMYJYdSv=Om2vbAM@`Qp{{SI=yP zj6WN*eEt0G$9EPX6FU%)-ho>hWTW!yzXBIo73<0umM-=@eG&niY^` zlG(|vuCl_x(X^Fob@=i{8+M5vWf7Bz=#aHGTNA;fZQyfbfueI8Z^639n`(DI%w^-^ zl`=@!u)r~Xf920-xd$Ab+S&PJY%K0H8a_J8uN3^_!K1_NV$*e#*Y*6|)XpiW=9H`*`Xx7W%v@7{XDma1?v0a%(K6rI&1!a YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/artifacts/0.9/doc/apidocs/stylesheet.css b/artifacts/0.9/doc/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/artifacts/0.9/doc/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/release.txt b/release.txt new file mode 100644 index 0000000..4dfe61a --- /dev/null +++ b/release.txt @@ -0,0 +1,12 @@ +HOWTO make a release: + +- mvn release:prepare in trunk (will ask for gpg passphrase) +- mvn release:perform in trunk +- step 8 in https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide +- mkdir -p artifacts//doc/ +- cp -r trunk/target/checkout/target/apidocs artifacts//doc/ +- svn add artifacts/ +- find -name '*.html' -exec svn propset svn:mime-type text/html {} \; +- svn commit +- update documentation +- provide new download on google code diff --git a/tags/ipv6-0.1/pom.xml b/tags/ipv6-0.1/pom.xml new file mode 100644 index 0000000..e9d2b86 --- /dev/null +++ b/tags/ipv6-0.1/pom.xml @@ -0,0 +1,41 @@ + + 4.0.0 + be.jvb.ipv6 + ipv6 + 0.1 + jar + IPv6 + + https://java-ipv6.googlecode.com/svn/tags/ipv6-0.1 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/ipv6-0.1 + + + + junit + junit + 4.10 + test + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.7 + 1.7 + + + + + + diff --git a/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6Address.java b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6Address.java new file mode 100644 index 0000000..9c062a6 --- /dev/null +++ b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6Address.java @@ -0,0 +1,299 @@ +package be.jvb.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private final long highBits; + + private final long lowBits; + + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = IPv6AddressHelpers.expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(long value) + { + final long newLowBits = lowBits + value; + if ((lowBits < 0 && newLowBits >= 0) || (lowBits >= 0 && newLowBits < 0)) + { + // sign changes indicate carry out -> carry out from low bits into high bits + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + return new IPv6Address(highBits, newLowBits); + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(long value) + { + final long newLowBits = lowBits - value; + if ((lowBits < 0 && newLowBits >= 0) || (lowBits >= 0 && newLowBits < 0)) + { + // sign changes indicate carry out -> carry out from high bits into low bits + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + return new IPv6Address(highBits, newLowBits); + } + } + + /** + * Mask the address with the given prefix length. + * + * @param prefixLength prefix length + * @return an address of which the last 128 - prefixLength bits are zero + */ + public IPv6Address maskWithPrefixLength(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + if (prefixLength == 128) + { + return this; + } + else if (prefixLength == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (prefixLength > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - prefixLength)), 0); + } + } + + /** + * Calculate the maximum address with the given prefix length. + * + * @param prefixLength prefix length + * @return an address of which the last 128 - prefixLength bits are one + */ + public IPv6Address maximumAddressWithPrefixLength(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + if (prefixLength == 128) + { + return this; + } + else if (prefixLength == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> prefixLength), 0xFFFFFFFFFFFFFFFFL); + } + } + + @Override + public String toString() + { + final String[] strings = toStringArray(); + + final StringBuilder result = new StringBuilder(); + + boolean shortHandNotationUsed = false; + boolean shortHandNotationBusy = false; + for (int i = 0; i < strings.length; i++) + { + if (!shortHandNotationUsed && i < N_SHORTS - 1 && IPv6AddressHelpers.isZeroString(strings[i]) && IPv6AddressHelpers + .isZeroString(strings[i + 1])) + { + shortHandNotationUsed = true; + shortHandNotationBusy = true; + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(IPv6AddressHelpers.isZeroString(strings[i]) && shortHandNotationBusy)) + { + shortHandNotationBusy = false; + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toStringArray() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%X", shorts[i]); + } + return strings; + } + + public short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + int numberOfTrailingZeroes() + { + return lowBits == 0 ? Long.numberOfTrailingZeros(highBits) + 64 : Long.numberOfTrailingZeros(lowBits); + } + + int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + +} diff --git a/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..40e229f --- /dev/null +++ b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,110 @@ +package be.jvb.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressPool.java b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..3291219 --- /dev/null +++ b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressPool.java @@ -0,0 +1,303 @@ +package be.jvb.ipv6; + + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool extends IPv6AddressRange +{ + private final SortedSet freeRanges; + + private final int prefixLength; + + /** + * Create a pool in between the given first and last address (inclusive) which is completely free. The given prefix length is the prefix + * length used for allocating subnets from this range. The whole range should be "aligned" on a multiple of subnets of this prefix + * length (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given prefix + * length). + * + * @param first first ip address of the range + * @param last last ip address of the range + * @param prefixLength prefix length with which to allocate subnets from this range + */ + public IPv6AddressPool(final IPv6Address first, final IPv6Address last, final int prefixLength) + { + // in the beginning, all is free + this(first, last, prefixLength, new TreeSet(Arrays.asList(new IPv6AddressRange(first, last)))); + } + + /** + * Private constructor to construct a pool with a given set of free ranges. + * + * @param first first ip address of the range + * @param last last ip address of the range + * @param prefixLength prefix length with which to allocate subnets from this range + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6Address first, final IPv6Address last, final int prefixLength, + final SortedSet freeRanges) + { + super(first, last); + + this.prefixLength = prefixLength; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + + validateFreeRanges(first, last, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenPrefixLength(first, last, prefixLength); + } + + private void validateFreeRanges(IPv6Address first, IPv6Address last, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(first, last, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be usefull. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6Address first, IPv6Address last, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(first) >= 0 && toValidate.last().getLast().compareTo(last) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenPrefixLength(IPv6Address first, IPv6Address last, int prefixLength) + { + final int allocatableBits = 128 - prefixLength; + + if (first.numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + prefixLength + "], first address should end with " + + allocatableBits + " zero bits"); + + if (last.numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + prefixLength + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = new IPv6Network(firstFreeRange.getFirst(), prefixLength); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (toAllocate.getPrefixLength() != this.prefixLength) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + prefixLength); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(getFirst(), getLast(), prefixLength, newFreeRanges); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(new IPv6AddressRange(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(new IPv6AddressRange(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(new IPv6AddressRange(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(getFirst(), getLast(), prefixLength, newFreeRanges); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (network.getPrefixLength() != prefixLength) + throw new IllegalArgumentException( + "network of prefix length [" + network.getPrefixLength() + "] can not be free in a pool which uses prefix length [" + + prefixLength + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } +} diff --git a/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressRange.java b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..3ba031f --- /dev/null +++ b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6AddressRange.java @@ -0,0 +1,194 @@ +package be.jvb.ipv6; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + public IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(new IPv6AddressRange(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(new IPv6AddressRange(first, last.subtract(1))); + else + return Arrays.asList(new IPv6AddressRange(first, address.subtract(1)), + new IPv6AddressRange(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return new IPv6AddressRange(address, last); + else if (address.compareTo(last) > 0) + return new IPv6AddressRange(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(new IPv6AddressRange(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(new IPv6AddressRange(first, network.getLast().subtract(1))); + else + return Arrays.asList(new IPv6AddressRange(first, network.getFirst().subtract(1)), + new IPv6AddressRange(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + @Override + public int compareTo(IPv6AddressRange that) + { + if (this.first != that.first) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + return current = current.add(1); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6Network.java b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6Network.java new file mode 100644 index 0000000..479c68d --- /dev/null +++ b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6Network.java @@ -0,0 +1,114 @@ +package be.jvb.ipv6; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final int prefixLength; + + /** + * Construct from address and prefix length. + * + * @param address address + * @param prefixLength prefix length, in range ]0, 128] + */ + public IPv6Network(IPv6Address address, int prefixLength) + { + super(address.maskWithPrefixLength(prefixLength), address.maximumAddressWithPrefixLength(prefixLength)); + + this.address = address.maskWithPrefixLength(prefixLength); + this.prefixLength = prefixLength; + } + + /** + * Construct from first and last address. This will construct the smallest possible network ("longest prefix length") which contains + * both addresses. + * + * @param first first address + * @param last last address + */ + public IPv6Network(IPv6Address first, IPv6Address last) + { + super(first.maskWithPrefixLength(IPv6NetworkHelpers.longestPrefixLength(first, last)), + first.maximumAddressWithPrefixLength(IPv6NetworkHelpers.longestPrefixLength(first, last))); + + this.prefixLength = IPv6NetworkHelpers.longestPrefixLength(first, last); + this.address = this.getFirst(); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return new IPv6Network(networkAddress, prefixLength); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + prefixLength; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Network that = (IPv6Network) o; + + if (prefixLength != that.prefixLength) return false; + if (address != null ? !address.equals(that.address) : that.address != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = address != null ? address.hashCode() : 0; + result = 31 * result + prefixLength; + return result; + } + + public int getPrefixLength() + { + return prefixLength; + } +} diff --git a/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..ca4259d --- /dev/null +++ b/tags/ipv6-0.1/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,30 @@ +package be.jvb.ipv6; + +import java.util.BitSet; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = BitSet.valueOf(new long[]{first.getLowBits(), first.getHighBits()}); + final BitSet lastBits = BitSet.valueOf(new long[]{last.getLowBits(), last.getHighBits()}); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet firstBits, BitSet lastBits) + { + int result = 0; + for (int i = 127; i >= 0 && (firstBits.get(i) == lastBits.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/Examples.java b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/Examples.java new file mode 100644 index 0000000..686c2d4 --- /dev/null +++ b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/Examples.java @@ -0,0 +1,53 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +/** + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = new IPv6AddressRange(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6Network range = new IPv6Network(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = new IPv6AddressPool(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff"), 120); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..41abad5 --- /dev/null +++ b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,171 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + new IPv6AddressPool(fromString("2001::1"), fromString("2001::ffff:ffff"), 120); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:fffe"), 120); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::ab00"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::abcd:ef00"), fromString("2001::abcd:efff"), 120); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(new IPv6Network(fromString("::1"), 128)); + + assertTrue(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::5"), 128); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("::" + i), 128))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("2001::"), fromString("2001::ffff:ffff"), 120); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::ffff:0"), 120))); + + pool = pool.deAllocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(new IPv6Network(fromString("::1"), 128)); + + assertFalse(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate(new IPv6Network(fromString("::1"), 128))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool.allocate(new IPv6Network(fromString("::99"), 128)); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::5"), 128); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(new IPv6Network(fromString("::" + i), 128)); + assertFalse(pool.isFree(new IPv6Network(fromString("::" + i), 128))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("2001::"), fromString("2001::ffff:ffff"), 120); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(new IPv6Network(fromString("2001::"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(new IPv6Network(fromString("2001::200"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::ffff:0"), 120))); + + pool = pool.deAllocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + } + +} diff --git a/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..7c5d055 --- /dev/null +++ b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,90 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + new IPv6AddressRange(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")).size()); + assertEquals(1, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")).size()); + assertEquals(1, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")).size()); + assertEquals(0, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")).size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + +} diff --git a/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressTest.java b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..eb4594b --- /dev/null +++ b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6AddressTest.java @@ -0,0 +1,221 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static be.jvb.ipv6.IPv6Address.fromInetAddress; +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Long.MAX_VALUE), fromString("::").add(Long.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Long.MAX_VALUE), fromString("::").subtract( + Long.MAX_VALUE).subtract( + Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final long randomLong = random.nextLong(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomLong).subtract(randomLong)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + assertEquals(randomAddress, randomAddress.add(Long.MAX_VALUE).subtract(Long.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Long.MIN_VALUE).subtract(Long.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(128)); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3::"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(64)); + assertEquals(fromString("2000::"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(15)); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithPrefixLength(1)); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithPrefixLength(128)); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithPrefixLength(64)); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithPrefixLength(1)); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithPrefixLength(1)); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + +} diff --git a/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..67d2675 --- /dev/null +++ b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,25 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..e4bc68a --- /dev/null +++ b/tags/ipv6-0.1/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java @@ -0,0 +1,42 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromFirstAndLastAddress() + { + assertEquals(new IPv6Network(fromString("::"), 126), new IPv6Network(fromString("::1"), fromString("::2"))); + assertEquals(new IPv6Network(fromString("a:b::"), 44), new IPv6Network(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", new IPv6Network(fromString("::"), 126).toString()); + assertEquals("a:b:c:d::/64", new IPv6Network(fromString("a:b:c:d::"), 64).toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = new IPv6Network(new IPv6Address(rg.nextLong(), rg.nextLong()), rg.nextInt(128) + 1); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + +} diff --git a/tags/ipv6-0.2/pom.xml b/tags/ipv6-0.2/pom.xml new file mode 100644 index 0000000..ffbcf0c --- /dev/null +++ b/tags/ipv6-0.2/pom.xml @@ -0,0 +1,48 @@ + + 4.0.0 + be.jvb.ipv6 + ipv6 + 0.2 + jar + IPv6 + + https://java-ipv6.googlecode.com/svn/tags/ipv6-0.2 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/ipv6-0.2 + + + + junit + junit + 4.10 + test + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.7 + 1.7 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + + diff --git a/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6Address.java b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6Address.java new file mode 100644 index 0000000..3655c0d --- /dev/null +++ b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6Address.java @@ -0,0 +1,305 @@ +package be.jvb.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import static be.jvb.ipv6.IPv6AddressHelpers.expandShortNotation; +import static be.jvb.ipv6.IPv6AddressHelpers.isLessThanUnsigned; +import static be.jvb.ipv6.IPv6AddressHelpers.isZeroString; +import static be.jvb.ipv6.IPv6AddressHelpers.mergeLongArrayIntoIPv6Address; +import static be.jvb.ipv6.IPv6AddressHelpers.parseStringArrayIntoLongArray; +import static java.lang.Long.numberOfTrailingZeros; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private final long highBits; + + private final long lowBits; + + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(long value) + { + final long newLowBits = lowBits + value; + if ((lowBits < 0 && newLowBits >= 0) || (lowBits >= 0 && newLowBits < 0)) + { + // sign changes indicate carry out -> carry out from low bits into high bits + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + return new IPv6Address(highBits, newLowBits); + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(long value) + { + final long newLowBits = lowBits - value; + if ((lowBits < 0 && newLowBits >= 0) || (lowBits >= 0 && newLowBits < 0)) + { + // sign changes indicate carry out -> carry out from high bits into low bits + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + return new IPv6Address(highBits, newLowBits); + } + } + + /** + * Mask the address with the given prefix length. + * + * @param prefixLength prefix length + * @return an address of which the last 128 - prefixLength bits are zero + */ + public IPv6Address maskWithPrefixLength(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + if (prefixLength == 128) + { + return this; + } + else if (prefixLength == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (prefixLength > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - prefixLength)), 0); + } + } + + /** + * Calculate the maximum address with the given prefix length. + * + * @param prefixLength prefix length + * @return an address of which the last 128 - prefixLength bits are one + */ + public IPv6Address maximumAddressWithPrefixLength(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + if (prefixLength == 128) + { + return this; + } + else if (prefixLength == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> prefixLength), 0xFFFFFFFFFFFFFFFFL); + } + } + + @Override + public String toString() + { + final String[] strings = toStringArray(); + + final StringBuilder result = new StringBuilder(); + + boolean shortHandNotationUsed = false; + boolean shortHandNotationBusy = false; + for (int i = 0; i < strings.length; i++) + { + if (!shortHandNotationUsed && i < N_SHORTS - 1 && isZeroString(strings[i]) && isZeroString(strings[i + 1])) + { + shortHandNotationUsed = true; + shortHandNotationBusy = true; + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(isZeroString(strings[i]) && shortHandNotationBusy)) + { + shortHandNotationBusy = false; + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toStringArray() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%X", shorts[i]); + } + return strings; + } + + public short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + int numberOfTrailingZeroes() + { + return lowBits == 0 ? numberOfTrailingZeros(highBits) + 64 : numberOfTrailingZeros(lowBits); + } + + int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + numberOfTrailingZeros(plusOne.getLowBits()); + } + +} diff --git a/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..40e229f --- /dev/null +++ b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,110 @@ +package be.jvb.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressPool.java b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..36feb0e --- /dev/null +++ b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressPool.java @@ -0,0 +1,332 @@ +package be.jvb.ipv6; + + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final int prefixLength; + + /** + * Create a pool in between the given first and last address (inclusive) which is completely free. The given prefix length is the prefix + * length used for allocating subnets from this range. The whole range should be "aligned" on a multiple of subnets of this prefix + * length (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given prefix + * length). + * + * @param first first ip address of the range + * @param last last ip address of the range + * @param prefixLength prefix length with which to allocate subnets from this range + */ + public IPv6AddressPool(final IPv6Address first, final IPv6Address last, final int prefixLength) + { + // in the beginning, all is free + this(first, last, prefixLength, new TreeSet(Arrays.asList(new IPv6AddressRange(first, last)))); + } + + /** + * Private constructor to construct a pool with a given set of free ranges. + * + * @param first first ip address of the range + * @param last last ip address of the range + * @param prefixLength prefix length with which to allocate subnets from this range + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6Address first, final IPv6Address last, final int prefixLength, + final SortedSet freeRanges) + { + this.underlyingRange = new IPv6AddressRange(first, last); + + this.prefixLength = prefixLength; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + + validateFreeRanges(first, last, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenPrefixLength(first, last, prefixLength); + } + + private void validateFreeRanges(IPv6Address first, IPv6Address last, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(first, last, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be usefull. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6Address first, IPv6Address last, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(first) >= 0 && toValidate.last().getLast().compareTo(last) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenPrefixLength(IPv6Address first, IPv6Address last, int prefixLength) + { + final int allocatableBits = 128 - prefixLength; + + if (first.numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + prefixLength + "], first address should end with " + + allocatableBits + " zero bits"); + + if (last.numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + prefixLength + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = new IPv6Network(firstFreeRange.getFirst(), prefixLength); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (toAllocate.getPrefixLength() != this.prefixLength) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + prefixLength); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(getFirst(), getLast(), prefixLength, newFreeRanges); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(new IPv6AddressRange(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(new IPv6AddressRange(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(new IPv6AddressRange(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(getFirst(), getLast(), prefixLength, newFreeRanges); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (network.getPrefixLength() != prefixLength) + throw new IllegalArgumentException( + "network of prefix length [" + network.getPrefixLength() + "] can not be free in a pool which uses prefix length [" + + prefixLength + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } +} diff --git a/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressRange.java b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..3ba031f --- /dev/null +++ b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6AddressRange.java @@ -0,0 +1,194 @@ +package be.jvb.ipv6; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + public IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(new IPv6AddressRange(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(new IPv6AddressRange(first, last.subtract(1))); + else + return Arrays.asList(new IPv6AddressRange(first, address.subtract(1)), + new IPv6AddressRange(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return new IPv6AddressRange(address, last); + else if (address.compareTo(last) > 0) + return new IPv6AddressRange(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(new IPv6AddressRange(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(new IPv6AddressRange(first, network.getLast().subtract(1))); + else + return Arrays.asList(new IPv6AddressRange(first, network.getFirst().subtract(1)), + new IPv6AddressRange(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + @Override + public int compareTo(IPv6AddressRange that) + { + if (this.first != that.first) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + return current = current.add(1); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6Network.java b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6Network.java new file mode 100644 index 0000000..430f5cb --- /dev/null +++ b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6Network.java @@ -0,0 +1,116 @@ +package be.jvb.ipv6; + +import static be.jvb.ipv6.IPv6NetworkHelpers.longestPrefixLength; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final int prefixLength; + + /** + * Construct from address and prefix length. + * + * @param address address + * @param prefixLength prefix length, in range ]0, 128] + */ + public IPv6Network(IPv6Address address, int prefixLength) + { + super(address.maskWithPrefixLength(prefixLength), address.maximumAddressWithPrefixLength(prefixLength)); + + this.address = address.maskWithPrefixLength(prefixLength); + this.prefixLength = prefixLength; + } + + /** + * Construct from first and last address. This will construct the smallest possible network ("longest prefix length") which contains + * both addresses. + * + * @param first first address + * @param last last address + */ + public IPv6Network(IPv6Address first, IPv6Address last) + { + super(first.maskWithPrefixLength(longestPrefixLength(first, last)), + first.maximumAddressWithPrefixLength(longestPrefixLength(first, last))); + + this.prefixLength = longestPrefixLength(first, last); + this.address = this.getFirst(); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return new IPv6Network(networkAddress, prefixLength); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + prefixLength; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Network that = (IPv6Network) o; + + if (prefixLength != that.prefixLength) return false; + if (address != null ? !address.equals(that.address) : that.address != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = address != null ? address.hashCode() : 0; + result = 31 * result + prefixLength; + return result; + } + + public int getPrefixLength() + { + return prefixLength; + } +} diff --git a/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..ca4259d --- /dev/null +++ b/tags/ipv6-0.2/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,30 @@ +package be.jvb.ipv6; + +import java.util.BitSet; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = BitSet.valueOf(new long[]{first.getLowBits(), first.getHighBits()}); + final BitSet lastBits = BitSet.valueOf(new long[]{last.getLowBits(), last.getHighBits()}); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet firstBits, BitSet lastBits) + { + int result = 0; + for (int i = 127; i >= 0 && (firstBits.get(i) == lastBits.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/Examples.java b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/Examples.java new file mode 100644 index 0000000..686c2d4 --- /dev/null +++ b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/Examples.java @@ -0,0 +1,53 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +/** + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = new IPv6AddressRange(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6Network range = new IPv6Network(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = new IPv6AddressPool(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff"), 120); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..41abad5 --- /dev/null +++ b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,171 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + new IPv6AddressPool(fromString("2001::1"), fromString("2001::ffff:ffff"), 120); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:fffe"), 120); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::ab00"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::abcd:ef00"), fromString("2001::abcd:efff"), 120); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(new IPv6Network(fromString("::1"), 128)); + + assertTrue(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::5"), 128); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("::" + i), 128))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("2001::"), fromString("2001::ffff:ffff"), 120); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::ffff:0"), 120))); + + pool = pool.deAllocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(new IPv6Network(fromString("::1"), 128)); + + assertFalse(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate(new IPv6Network(fromString("::1"), 128))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool.allocate(new IPv6Network(fromString("::99"), 128)); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::5"), 128); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(new IPv6Network(fromString("::" + i), 128)); + assertFalse(pool.isFree(new IPv6Network(fromString("::" + i), 128))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("2001::"), fromString("2001::ffff:ffff"), 120); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(new IPv6Network(fromString("2001::"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(new IPv6Network(fromString("2001::200"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::ffff:0"), 120))); + + pool = pool.deAllocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + } + +} diff --git a/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..7c5d055 --- /dev/null +++ b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,90 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + new IPv6AddressRange(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")).size()); + assertEquals(1, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")).size()); + assertEquals(1, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")).size()); + assertEquals(0, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")).size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + +} diff --git a/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressTest.java b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..eb4594b --- /dev/null +++ b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6AddressTest.java @@ -0,0 +1,221 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static be.jvb.ipv6.IPv6Address.fromInetAddress; +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Long.MAX_VALUE), fromString("::").add(Long.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Long.MAX_VALUE), fromString("::").subtract( + Long.MAX_VALUE).subtract( + Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final long randomLong = random.nextLong(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomLong).subtract(randomLong)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + assertEquals(randomAddress, randomAddress.add(Long.MAX_VALUE).subtract(Long.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Long.MIN_VALUE).subtract(Long.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(128)); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3::"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(64)); + assertEquals(fromString("2000::"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(15)); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithPrefixLength(1)); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithPrefixLength(128)); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithPrefixLength(64)); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithPrefixLength(1)); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithPrefixLength(1)); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + +} diff --git a/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..67d2675 --- /dev/null +++ b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,25 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..e4bc68a --- /dev/null +++ b/tags/ipv6-0.2/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java @@ -0,0 +1,42 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromFirstAndLastAddress() + { + assertEquals(new IPv6Network(fromString("::"), 126), new IPv6Network(fromString("::1"), fromString("::2"))); + assertEquals(new IPv6Network(fromString("a:b::"), 44), new IPv6Network(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", new IPv6Network(fromString("::"), 126).toString()); + assertEquals("a:b:c:d::/64", new IPv6Network(fromString("a:b:c:d::"), 64).toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = new IPv6Network(new IPv6Address(rg.nextLong(), rg.nextLong()), rg.nextInt(128) + 1); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + +} diff --git a/tags/ipv6-0.3/pom.xml b/tags/ipv6-0.3/pom.xml new file mode 100644 index 0000000..3e6ec70 --- /dev/null +++ b/tags/ipv6-0.3/pom.xml @@ -0,0 +1,48 @@ + + 4.0.0 + be.jvb.ipv6 + ipv6 + 0.3 + jar + IPv6 + + https://java-ipv6.googlecode.com/svn/tags/ipv6-0.3 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/ipv6-0.3 + + + + junit + junit + 4.10 + test + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.7 + 1.7 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + + diff --git a/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6Address.java b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6Address.java new file mode 100644 index 0000000..e173317 --- /dev/null +++ b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6Address.java @@ -0,0 +1,341 @@ +package be.jvb.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import static be.jvb.ipv6.IPv6AddressHelpers.expandShortNotation; +import static be.jvb.ipv6.IPv6AddressHelpers.isLessThanUnsigned; +import static be.jvb.ipv6.IPv6AddressHelpers.isZeroString; +import static be.jvb.ipv6.IPv6AddressHelpers.mergeLongArrayIntoIPv6Address; +import static be.jvb.ipv6.IPv6AddressHelpers.parseStringArrayIntoLongArray; +import static java.lang.Long.numberOfTrailingZeros; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private final long highBits; + + private final long lowBits; + + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something postive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given prefix length. + * + * @param prefixLength prefix length + * @return an address of which the last 128 - prefixLength bits are zero + */ + public IPv6Address maskWithPrefixLength(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + if (prefixLength == 128) + { + return this; + } + else if (prefixLength == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (prefixLength > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - prefixLength)), 0); + } + } + + /** + * Calculate the maximum address with the given prefix length. + * + * @param prefixLength prefix length + * @return an address of which the last 128 - prefixLength bits are one + */ + public IPv6Address maximumAddressWithPrefixLength(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + if (prefixLength == 128) + { + return this; + } + else if (prefixLength == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> prefixLength), 0xFFFFFFFFFFFFFFFFL); + } + } + + @Override + public String toString() + { + final String[] strings = toStringArray(); + + final StringBuilder result = new StringBuilder(); + + boolean shortHandNotationUsed = false; + boolean shortHandNotationBusy = false; + for (int i = 0; i < strings.length; i++) + { + if (!shortHandNotationUsed && i < N_SHORTS - 1 && isZeroString(strings[i]) && isZeroString(strings[i + 1])) + { + shortHandNotationUsed = true; + shortHandNotationBusy = true; + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(isZeroString(strings[i]) && shortHandNotationBusy)) + { + shortHandNotationBusy = false; + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toStringArray() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%X", shorts[i]); + } + return strings; + } + + public short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + int numberOfTrailingZeroes() + { + return lowBits == 0 ? numberOfTrailingZeros(highBits) + 64 : numberOfTrailingZeros(lowBits); + } + + int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + numberOfTrailingZeros(plusOne.getLowBits()); + } + +} diff --git a/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..40e229f --- /dev/null +++ b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,110 @@ +package be.jvb.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressPool.java b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..863f077 --- /dev/null +++ b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressPool.java @@ -0,0 +1,459 @@ +package be.jvb.ipv6; + + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final int prefixLength; + + private final IPv6Network lastAllocated; + + /** + * Create a pool in between the given first and last address (inclusive) which is completely free. The given prefix length is the prefix + * length used for allocating subnets from this range. The whole range should be "aligned" on a multiple of subnets of this prefix + * length (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given prefix + * length). + * + * @param first first ip address of the range + * @param last last ip address of the range + * @param prefixLength prefix length with which to allocate subnets from this range + */ + public IPv6AddressPool(final IPv6Address first, final IPv6Address last, final int prefixLength) + { + // in the beginning, all is free + this(first, last, prefixLength, new TreeSet(Arrays.asList(new IPv6AddressRange(first, last))), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param first first ip address of the range + * @param last last ip address of the range + * @param prefixLength prefix length with which to allocate subnets from this range + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6Address first, final IPv6Address last, final int prefixLength, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = new IPv6AddressRange(first, last); + + this.prefixLength = prefixLength; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(first, last, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenPrefixLength(first, last, prefixLength); + } + + private void validateFreeRanges(IPv6Address first, IPv6Address last, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(first, last, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be usefull. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6Address first, IPv6Address last, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(first) >= 0 && toValidate.last().getLast().compareTo(last) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenPrefixLength(IPv6Address first, IPv6Address last, int prefixLength) + { + final int allocatableBits = 128 - prefixLength; + + if (first.numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + prefixLength + "], first address should end with " + + allocatableBits + " zero bits"); + + if (last.numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + prefixLength + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = new IPv6Network(firstFreeRange.getFirst(), prefixLength); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (toAllocate.getPrefixLength() != this.prefixLength) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + prefixLength); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(getFirst(), getLast(), prefixLength, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(new IPv6AddressRange(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(new IPv6AddressRange(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(new IPv6AddressRange(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(getFirst(), getLast(), prefixLength, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (network.getPrefixLength() != prefixLength) + throw new IllegalArgumentException( + "network of prefix length [" + network.getPrefixLength() + "] can not be free in a pool which uses prefix length [" + + prefixLength + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressPool)) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (prefixLength != that.prefixLength) return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + prefixLength; + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } +} diff --git a/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressRange.java b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..527eb98 --- /dev/null +++ b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6AddressRange.java @@ -0,0 +1,198 @@ +package be.jvb.ipv6; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + public IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(new IPv6AddressRange(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(new IPv6AddressRange(first, last.subtract(1))); + else + return Arrays.asList(new IPv6AddressRange(first, address.subtract(1)), + new IPv6AddressRange(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return new IPv6AddressRange(address, last); + else if (address.compareTo(last) > 0) + return new IPv6AddressRange(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(new IPv6AddressRange(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(new IPv6AddressRange(first, network.getFirst().subtract(1))); + else + return Arrays.asList(new IPv6AddressRange(first, network.getFirst().subtract(1)), + new IPv6AddressRange(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + @Override + public int compareTo(IPv6AddressRange that) + { + if (this.first != that.first) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + return current = current.add(1); + else + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6Network.java b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6Network.java new file mode 100644 index 0000000..430f5cb --- /dev/null +++ b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6Network.java @@ -0,0 +1,116 @@ +package be.jvb.ipv6; + +import static be.jvb.ipv6.IPv6NetworkHelpers.longestPrefixLength; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final int prefixLength; + + /** + * Construct from address and prefix length. + * + * @param address address + * @param prefixLength prefix length, in range ]0, 128] + */ + public IPv6Network(IPv6Address address, int prefixLength) + { + super(address.maskWithPrefixLength(prefixLength), address.maximumAddressWithPrefixLength(prefixLength)); + + this.address = address.maskWithPrefixLength(prefixLength); + this.prefixLength = prefixLength; + } + + /** + * Construct from first and last address. This will construct the smallest possible network ("longest prefix length") which contains + * both addresses. + * + * @param first first address + * @param last last address + */ + public IPv6Network(IPv6Address first, IPv6Address last) + { + super(first.maskWithPrefixLength(longestPrefixLength(first, last)), + first.maximumAddressWithPrefixLength(longestPrefixLength(first, last))); + + this.prefixLength = longestPrefixLength(first, last); + this.address = this.getFirst(); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return new IPv6Network(networkAddress, prefixLength); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + prefixLength; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Network that = (IPv6Network) o; + + if (prefixLength != that.prefixLength) return false; + if (address != null ? !address.equals(that.address) : that.address != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = address != null ? address.hashCode() : 0; + result = 31 * result + prefixLength; + return result; + } + + public int getPrefixLength() + { + return prefixLength; + } +} diff --git a/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..ca4259d --- /dev/null +++ b/tags/ipv6-0.3/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,30 @@ +package be.jvb.ipv6; + +import java.util.BitSet; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = BitSet.valueOf(new long[]{first.getLowBits(), first.getHighBits()}); + final BitSet lastBits = BitSet.valueOf(new long[]{last.getLowBits(), last.getHighBits()}); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet firstBits, BitSet lastBits) + { + int result = 0; + for (int i = 127; i >= 0 && (firstBits.get(i) == lastBits.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/Examples.java b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/Examples.java new file mode 100644 index 0000000..686c2d4 --- /dev/null +++ b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/Examples.java @@ -0,0 +1,53 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +/** + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = new IPv6AddressRange(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6Network range = new IPv6Network(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = new IPv6AddressPool(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff"), 120); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..8aed941 --- /dev/null +++ b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,224 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + new IPv6AddressPool(fromString("2001::1"), fromString("2001::ffff:ffff"), 120); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:fffe"), 120); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::ab00"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::abcd:ef00"), fromString("2001::abcd:efff"), 120); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(new IPv6Network(fromString("::1"), 128)); + + assertTrue(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::5"), 128); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("::" + i), 128))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("2001::"), fromString("2001::ffff:ffff"), 120); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("2001::"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("2001::100"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("2001::200"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::ffff:0"), 120))); + + pool = pool.deAllocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(new IPv6Network(fromString("::1"), 128)); + + assertFalse(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate(new IPv6Network(fromString("::1"), 128))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool.allocate(new IPv6Network(fromString("::99"), 128)); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::5"), 128); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(new IPv6Network(fromString("::" + i), 128)); + assertFalse(pool.isFree(new IPv6Network(fromString("::" + i), 128))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("2001::"), fromString("2001::ffff:ffff"), 120); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(new IPv6Network(fromString("2001::"), 120)); + assertEquals(new IPv6Network(fromString("2001::"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(new IPv6Network(fromString("2001::200"), 120)); + assertEquals(new IPv6Network(fromString("2001::200"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(new IPv6Network(fromString("2001::100"), 120)); + assertEquals(new IPv6Network(fromString("2001::100"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::ffff:0"), 120))); + + pool = pool.deAllocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), i); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::"), i), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::").maximumAddressWithPrefixLength(i).add(1), i), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::"), fromString("::ffff:ffff:ffff:ffff"), i); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::"), i), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::").maximumAddressWithPrefixLength(i).add(1), i), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = new IPv6AddressPool(fromString("::"), fromString("::ffff:ffff:ffff:ffff"), 66); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..7c5d055 --- /dev/null +++ b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,90 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + new IPv6AddressRange(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")).size()); + assertEquals(1, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")).size()); + assertEquals(1, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")).size()); + assertEquals(0, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")).size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + +} diff --git a/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressTest.java b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..5b4d9dd --- /dev/null +++ b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6AddressTest.java @@ -0,0 +1,220 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static be.jvb.ipv6.IPv6Address.fromInetAddress; +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(128)); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3::"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(64)); + assertEquals(fromString("2000::"), fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithPrefixLength(15)); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithPrefixLength(1)); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithPrefixLength(128)); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithPrefixLength(120)); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithPrefixLength(64)); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithPrefixLength(1)); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithPrefixLength(1)); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + +} diff --git a/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..67d2675 --- /dev/null +++ b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,25 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..e4bc68a --- /dev/null +++ b/tags/ipv6-0.3/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java @@ -0,0 +1,42 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromFirstAndLastAddress() + { + assertEquals(new IPv6Network(fromString("::"), 126), new IPv6Network(fromString("::1"), fromString("::2"))); + assertEquals(new IPv6Network(fromString("a:b::"), 44), new IPv6Network(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", new IPv6Network(fromString("::"), 126).toString()); + assertEquals("a:b:c:d::/64", new IPv6Network(fromString("a:b:c:d::"), 64).toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = new IPv6Network(new IPv6Address(rg.nextLong(), rg.nextLong()), rg.nextInt(128) + 1); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + +} diff --git a/tags/ipv6-0.4/pom.xml b/tags/ipv6-0.4/pom.xml new file mode 100644 index 0000000..15ee01f --- /dev/null +++ b/tags/ipv6-0.4/pom.xml @@ -0,0 +1,48 @@ + + 4.0.0 + be.jvb.ipv6 + ipv6 + 0.4 + jar + IPv6 + + https://java-ipv6.googlecode.com/svn/tags/ipv6-0.4 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/ipv6-0.4 + + + + junit + junit + 4.10 + test + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.7 + 1.7 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + + diff --git a/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6Address.java b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6Address.java new file mode 100644 index 0000000..c837cac --- /dev/null +++ b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6Address.java @@ -0,0 +1,349 @@ +package be.jvb.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import static be.jvb.ipv6.IPv6AddressHelpers.*; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private final long highBits; + + private final long lowBits; + + public IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something postive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * @return String representation of the IPv6 Address, using shorthand notation whenever possible. + */ + @Override + public String toString() + { + final String[] strings = toStringArray(); + + final StringBuilder result = new StringBuilder(); + + boolean shortHandNotationUsed = false; + boolean shortHandNotationBusy = false; + for (int i = 0; i < strings.length; i++) + { + if (!shortHandNotationUsed && i < N_SHORTS - 1 && isZeroString(strings[i]) && isZeroString(strings[i + 1])) + { + shortHandNotationUsed = true; + shortHandNotationBusy = true; + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(isZeroString(strings[i]) && shortHandNotationBusy)) + { + shortHandNotationBusy = false; + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toStringArray() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%X", shorts[i]); + } + return strings; + } + + public short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..40e229f --- /dev/null +++ b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,110 @@ +package be.jvb.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressPool.java b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..162b9e1 --- /dev/null +++ b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressPool.java @@ -0,0 +1,453 @@ +package be.jvb.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final int prefixLength; + + private final IPv6Network lastAllocated; + + /** + * Create a pool in between the given first and last address (inclusive) which is completely free. The given prefix length is the prefix + * length used for allocating subnets from this range. The whole range should be "aligned" on a multiple of subnets of this prefix + * length (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given prefix + * length). + * + * @param first first ip address of the range + * @param last last ip address of the range + * @param prefixLength prefix length with which to allocate subnets from this range + */ + public IPv6AddressPool(final IPv6Address first, final IPv6Address last, final int prefixLength) + { + // in the beginning, all is free + this(first, last, prefixLength, new TreeSet(Arrays.asList(new IPv6AddressRange(first, last))), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param first first ip address of the range + * @param last last ip address of the range + * @param prefixLength prefix length with which to allocate subnets from this range + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6Address first, final IPv6Address last, final int prefixLength, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = new IPv6AddressRange(first, last); + + this.prefixLength = prefixLength; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(first, last, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenPrefixLength(first, last, prefixLength); + } + + private void validateFreeRanges(IPv6Address first, IPv6Address last, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(first, last, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be usefull. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6Address first, IPv6Address last, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(first) >= 0 && toValidate.last().getLast().compareTo(last) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenPrefixLength(IPv6Address first, IPv6Address last, int prefixLength) + { + final int allocatableBits = 128 - prefixLength; + + if (first.numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + prefixLength + "], first address should end with " + + allocatableBits + " zero bits"); + + if (last.numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + prefixLength + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = new IPv6Network(firstFreeRange.getFirst(), prefixLength); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (toAllocate.getPrefixLength() != this.prefixLength) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + prefixLength); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(getFirst(), getLast(), prefixLength, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(new IPv6AddressRange(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(new IPv6AddressRange(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(new IPv6AddressRange(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(getFirst(), getLast(), prefixLength, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (network.getPrefixLength() != prefixLength) + throw new IllegalArgumentException( + "network of prefix length [" + network.getPrefixLength() + "] can not be free in a pool which uses prefix length [" + + prefixLength + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressPool)) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (prefixLength != that.prefixLength) return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + prefixLength; + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } +} diff --git a/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressRange.java b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..59331f2 --- /dev/null +++ b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6AddressRange.java @@ -0,0 +1,194 @@ +package be.jvb.ipv6; + +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + public IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(new IPv6AddressRange(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(new IPv6AddressRange(first, last.subtract(1))); + else + return Arrays.asList(new IPv6AddressRange(first, address.subtract(1)), + new IPv6AddressRange(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return new IPv6AddressRange(address, last); + else if (address.compareTo(last) > 0) + return new IPv6AddressRange(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(new IPv6AddressRange(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(new IPv6AddressRange(first, network.getFirst().subtract(1))); + else + return Arrays.asList(new IPv6AddressRange(first, network.getFirst().subtract(1)), + new IPv6AddressRange(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + @Override + public int compareTo(IPv6AddressRange that) + { + if (this.first != that.first) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + return current = current.add(1); + else + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6Network.java b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6Network.java new file mode 100644 index 0000000..04315a7 --- /dev/null +++ b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6Network.java @@ -0,0 +1,140 @@ +package be.jvb.ipv6; + +import static be.jvb.ipv6.IPv6NetworkHelpers.longestPrefixLength; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + public IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Construct from address and prefix length. + * + * @param address address + * @param prefixLength prefix length + */ + public IPv6Network(IPv6Address address, int prefixLength) + { + super(address.maskWithNetworkMask(new IPv6NetworkMask(prefixLength)), + address.maximumAddressWithNetworkMask(new IPv6NetworkMask(prefixLength))); + + final IPv6NetworkMask networkMask = new IPv6NetworkMask(prefixLength); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Construct from first and last address. This will construct the smallest possible network ("longest prefix length") which contains + * both addresses. + * + * @param first first address + * @param last last address + */ + public IPv6Network(IPv6Address first, IPv6Address last) + { + super(first.maskWithNetworkMask(new IPv6NetworkMask(longestPrefixLength(first, last))), + first.maximumAddressWithNetworkMask(new IPv6NetworkMask(longestPrefixLength(first, last)))); + + this.networkMask = new IPv6NetworkMask(longestPrefixLength(first, last)); + this.address = this.getFirst(); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return new IPv6Network(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public int getPrefixLength() + { + return networkMask.asPrefixLength(); + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } +} diff --git a/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..ad11633 --- /dev/null +++ b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,30 @@ +package be.jvb.ipv6; + +import java.util.BitSet; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = BitSet.valueOf(new long[]{first.getLowBits(), first.getHighBits()}); + final BitSet lastBits = BitSet.valueOf(new long[]{last.getLowBits(), last.getHighBits()}); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6NetworkMask.java b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..8b0d469 --- /dev/null +++ b/tags/ipv6-0.4/src/main/java/be/jvb/ipv6/IPv6NetworkMask.java @@ -0,0 +1,120 @@ +package be.jvb.ipv6; + +import java.util.BitSet; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public IPv6NetworkMask(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + this.prefixLength = iPv6Address.numberOfLeadingOnes(); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public IPv6NetworkMask(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + this.prefixLength = prefixLength; + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = BitSet.valueOf(new long[]{addressToValidate.getLowBits(), addressToValidate.getHighBits()}); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return asAddress().toString(); + } +} diff --git a/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..5173bb3 --- /dev/null +++ b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,223 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + new IPv6AddressPool(fromString("2001::1"), fromString("2001::ffff:ffff"), 120); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:fffe"), 120); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::ab00"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:ffff"), 120); + new IPv6AddressPool(fromString("2001::abcd:ef00"), fromString("2001::abcd:efff"), 120); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(new IPv6Network(fromString("::1"), 128)); + + assertTrue(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::5"), 128); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("::" + i), 128))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("2001::"), fromString("2001::ffff:ffff"), 120); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("2001::"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("2001::100"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("2001::200"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::ffff:0"), 120))); + + pool = pool.deAllocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(new IPv6Network(fromString("::1"), 128)); + + assertFalse(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate(new IPv6Network(fromString("::1"), 128))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), 128); + assertFalse(pool.isExhausted()); + + pool.allocate(new IPv6Network(fromString("::99"), 128)); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::5"), 128); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(new IPv6Network(fromString("::" + i), 128)); + assertFalse(pool.isFree(new IPv6Network(fromString("::" + i), 128))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("2001::"), fromString("2001::ffff:ffff"), 120); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(new IPv6Network(fromString("2001::"), 120)); + assertEquals(new IPv6Network(fromString("2001::"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(new IPv6Network(fromString("2001::200"), 120)); + assertEquals(new IPv6Network(fromString("2001::200"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(new IPv6Network(fromString("2001::100"), 120)); + assertEquals(new IPv6Network(fromString("2001::100"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::ffff:0"), 120))); + + pool = pool.deAllocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), i); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::"), i), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), i), + pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::"), fromString("::ffff:ffff:ffff:ffff"), i); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::"), i), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), i), + pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = new IPv6AddressPool(fromString("::"), fromString("::ffff:ffff:ffff:ffff"), 66); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..7c5d055 --- /dev/null +++ b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,90 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + new IPv6AddressRange(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")).size()); + assertEquals(1, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")).size()); + assertEquals(1, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")).size()); + assertEquals(0, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")).size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + +} diff --git a/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressTest.java b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..03ec8cc --- /dev/null +++ b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6AddressTest.java @@ -0,0 +1,251 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static be.jvb.ipv6.IPv6Address.fromInetAddress; +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + +} diff --git a/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..67d2675 --- /dev/null +++ b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,25 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkMaskTest.java b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..cdc5794 --- /dev/null +++ b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,42 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Zero() + { + new IPv6NetworkMask(0); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + new IPv6NetworkMask(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..1745168 --- /dev/null +++ b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/IPv6NetworkTest.java @@ -0,0 +1,68 @@ +package be.jvb.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static be.jvb.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromFirstAndLastAddress() + { + assertEquals(new IPv6Network(fromString("::"), 126), new IPv6Network(fromString("::1"), fromString("::2"))); + assertEquals(new IPv6Network(fromString("a:b::"), 44), new IPv6Network(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", new IPv6Network(fromString("::"), 126).toString()); + assertEquals("a:b:c:d::/64", new IPv6Network(fromString("a:b:c:d::"), 64).toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = new IPv6Network(new IPv6Address(rg.nextLong(), rg.nextLong()), rg.nextInt(128) + 1); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(new IPv6NetworkMask(new IPv6Address(0x8000000000000000L, 0x0L)), IPv6Network.fromString("a:b:c::/1").getNetmask()); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xfffffffffffffffeL, 0x0L)), IPv6Network.fromString("a:b:c::/63").getNetmask()); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0x0L)), IPv6Network.fromString("a:b:c::/64").getNetmask()); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + + +} diff --git a/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/examples/Examples.java b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/examples/Examples.java new file mode 100644 index 0000000..6e67bfd --- /dev/null +++ b/tags/ipv6-0.4/src/test/java/be/jvb/ipv6/examples/Examples.java @@ -0,0 +1,93 @@ +package be.jvb.ipv6.examples; + +import be.jvb.ipv6.*; +import org.junit.Test; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only + * to call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = new IPv6AddressRange(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6Network range = new IPv6Network(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask()); // prints ffff:ffff:ffe0:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = new IPv6NetworkMask(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = new IPv6NetworkMask(IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = new IPv6NetworkMask(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(new IPv6NetworkMask(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(new IPv6NetworkMask(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = new IPv6AddressPool(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff"), 120); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.10/LICENSE b/tags/java-ipv6-0.10/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/tags/java-ipv6-0.10/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/tags/java-ipv6-0.10/NOTICE b/tags/java-ipv6-0.10/NOTICE new file mode 100644 index 0000000..a4605c4 --- /dev/null +++ b/tags/java-ipv6-0.10/NOTICE @@ -0,0 +1,2 @@ + Java IPv6 + Copyright 2013 Jan Van Besien \ No newline at end of file diff --git a/tags/java-ipv6-0.10/pom.xml b/tags/java-ipv6-0.10/pom.xml new file mode 100644 index 0000000..c550679 --- /dev/null +++ b/tags/java-ipv6-0.10/pom.xml @@ -0,0 +1,143 @@ + + + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.10 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.10 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.10 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.10 + + + + + junit + junit + 4.10 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + ${basedir} + false + + LICENSE + NOTICE + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/BitSetHelpers.java b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/BitSetHelpers.java new file mode 100644 index 0000000..698c51e --- /dev/null +++ b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/BitSetHelpers.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + * method. However, for java-6 compatibility, we go this way. + * + * @author Jan Van Besien + */ +class BitSetHelpers +{ + static BitSet bitSetOf(long lowerBits, long upperBits) + { + final BitSet bitSet = new BitSet(); + convert(lowerBits, 0, bitSet); + convert(upperBits, Long.SIZE, bitSet); + return bitSet; + } + + static void convert(long value, int bitSetOffset, BitSet bits) + { + int index = 0; + while (value != 0L) + { + if (value % 2L != 0) + { + bits.set(bitSetOffset + index); + } + ++index; + value = value >>> 1; + } + } + +} diff --git a/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..5776bfe --- /dev/null +++ b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,402 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private final long highBits; + + private final long lowBits; + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = IPv6AddressHelpers.expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something postive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() == 0) + { + return new IPv6Address(0, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * @return String representation of the IPv6 address, using shorthand notation whenever possible. + */ + @Override + public String toString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + boolean shortHandNotationUsed = false; + boolean shortHandNotationBusy = false; + for (int i = 0; i < strings.length; i++) + { + if (!shortHandNotationUsed && i < N_SHORTS - 1 && IPv6AddressHelpers.isZeroString(strings[i]) && IPv6AddressHelpers + .isZeroString(strings[i + 1])) + { + shortHandNotationUsed = true; + shortHandNotationBusy = true; + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(IPv6AddressHelpers.isZeroString(strings[i]) && shortHandNotationBusy)) + { + shortHandNotationBusy = false; + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + public short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..edf129a --- /dev/null +++ b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,126 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..77b9a0f --- /dev/null +++ b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,483 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..309335e --- /dev/null +++ b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,232 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + /** + * The natural order of {@link com.googlecode.ipv6.IPv6AddressRange}s orders them on increasing first addresses, and on increasing last + * address if the first address would be equal. + *

+ * Note that the natural order does thus not compare sizes of ranges. + * + * @param that range to compare with + * @return negative, zero or positive depending on whether this is smaller, equal or greater than that + */ + @Override + public int compareTo(IPv6AddressRange that) + { + if (!this.first.equals(that.first)) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + return current = current.add(1); + else + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..60aa407 --- /dev/null +++ b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,149 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } +} diff --git a/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..66268ed --- /dev/null +++ b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = bitSetOf(first.getLowBits(), first.getHighBits()); + final BitSet lastBits = bitSetOf(last.getLowBits(), last.getHighBits()); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..ee4394b --- /dev/null +++ b/tags/java-ipv6-0.10/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,150 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength < 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval [0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = bitSetOf(addressToValidate.getLowBits(), addressToValidate.getHighBits()); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..834d561 --- /dev/null +++ b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,274 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..e699741 --- /dev/null +++ b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,135 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import junit.framework.Assert; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + IPv6AddressRange.fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + + @Test + public void compareTo() + { + final IPv6AddressRange a = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange b = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange c = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange d = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + + Assert.assertTrue(a.compareTo(b) > 0); + Assert.assertTrue(a.compareTo(c) < 0); + Assert.assertTrue(a.compareTo(d) < 0); + Assert.assertTrue(b.compareTo(c) < 0); + Assert.assertTrue(b.compareTo(d) < 0); + Assert.assertTrue(c.compareTo(d) > 0); + + Assert.assertTrue(a.compareTo(a) == 0); + Assert.assertTrue(b.compareTo(b) == 0); + Assert.assertTrue(c.compareTo(c) == 0); + Assert.assertTrue(d.compareTo(d) == 0); + } +} diff --git a/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..f13e41a --- /dev/null +++ b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,278 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + +} diff --git a/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..960d630 --- /dev/null +++ b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..0eea592 --- /dev/null +++ b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Negative() + { + new IPv6NetworkMask(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..a40b1bb --- /dev/null +++ b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + + @Test + public void contains() + { + assertTrue(IPv6Network.fromString("ffff::/8").contains(IPv6Address.fromString("ffff::1"))); + assertTrue(IPv6Network.fromString("1234:5678:1234:5678::/64").contains(IPv6Address.fromString("1234:5678:1234:5678:1::"))); + } + + @Test + public void zeroNetworkContainsEverything() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + + assertTrue(IPv6Network.fromString("::/0").contains(randomAddress)); + assertTrue(IPv6Network.fromString("abcd:effe:dcba::/0").contains(randomAddress)); + } +} diff --git a/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..380dc60 --- /dev/null +++ b/tags/java-ipv6-0.10/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,113 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.11/LICENSE b/tags/java-ipv6-0.11/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/tags/java-ipv6-0.11/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/tags/java-ipv6-0.11/NOTICE b/tags/java-ipv6-0.11/NOTICE new file mode 100644 index 0000000..a4605c4 --- /dev/null +++ b/tags/java-ipv6-0.11/NOTICE @@ -0,0 +1,2 @@ + Java IPv6 + Copyright 2013 Jan Van Besien \ No newline at end of file diff --git a/tags/java-ipv6-0.11/pom.xml b/tags/java-ipv6-0.11/pom.xml new file mode 100644 index 0000000..4102d46 --- /dev/null +++ b/tags/java-ipv6-0.11/pom.xml @@ -0,0 +1,143 @@ + + + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.11 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.11 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.11 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.11 + + + + + junit + junit + 4.10 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + ${basedir} + false + + LICENSE + NOTICE + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/BitSetHelpers.java b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/BitSetHelpers.java new file mode 100644 index 0000000..698c51e --- /dev/null +++ b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/BitSetHelpers.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + * method. However, for java-6 compatibility, we go this way. + * + * @author Jan Van Besien + */ +class BitSetHelpers +{ + static BitSet bitSetOf(long lowerBits, long upperBits) + { + final BitSet bitSet = new BitSet(); + convert(lowerBits, 0, bitSet); + convert(upperBits, Long.SIZE, bitSet); + return bitSet; + } + + static void convert(long value, int bitSetOffset, BitSet bits) + { + int index = 0; + while (value != 0L) + { + if (value % 2L != 0) + { + bits.set(bitSetOffset + index); + } + ++index; + value = value >>> 1; + } + } + +} diff --git a/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..8bd3788 --- /dev/null +++ b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,470 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.LongBuffer; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private static final int N_BYTES = 16; + + private final long highBits; + + private final long lowBits; + + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + * IPv6Addresses from a {@link String} or an {@link java.net.InetAddress}. The internal representation of an IPv6Address is exactly + * these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + public static IPv6Address fromLongs(long highBits, long lowBits) + { + return new IPv6Address(highBits, lowBits); + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = IPv6AddressHelpers.expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Create an IPv6 address from a byte array. + * + * @param bytes byte array with 16 bytes + * @return IPv6 address + */ + public static IPv6Address fromByteArray(final byte[] bytes) + { + if (bytes == null) + throw new IllegalArgumentException("can not construct from [null]"); + if (bytes.length != N_BYTES) + throw new IllegalArgumentException("the byte array to construct from should be 16 bytes long"); + + ByteBuffer buf = ByteBuffer.allocate(N_BYTES); + for (byte b : bytes) + { + buf.put(b); + } + + buf.rewind(); + LongBuffer longBuffer = buf.asLongBuffer(); + return new IPv6Address(longBuffer.get(), longBuffer.get()); + } + + public byte[] toByteArray() + { + ByteBuffer byteBuffer = ByteBuffer.allocate(N_BYTES).putLong(highBits).putLong(lowBits); + return byteBuffer.array(); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something positive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() == 0) + { + return new IPv6Address(0, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * @return String representation of the IPv6 address, using shorthand notation whenever possible. + */ + @Override + public String toString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + int[] shortHandNotationPositionAndLength = startAndLengthOfLongestRunOfZeroes(); + int shortHandNotationPosition = shortHandNotationPositionAndLength[0]; + int shortHandNotationLength = shortHandNotationPositionAndLength[1]; + + for (int i = 0; i < strings.length; i++) + { + if (i == shortHandNotationPosition) + { + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(i > shortHandNotationPosition && i < shortHandNotationPosition + shortHandNotationLength)) + { + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + private short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + int[] startAndLengthOfLongestRunOfZeroes() + { + int longestConsecutiveZeroes = 0; + int longestConsecutiveZeroesPos = -1; + short[] shorts = toShortArray(); + for (int pos = 0; pos < shorts.length; pos++) + { + int consecutiveZeroesAtCurrentPos = countConsecutiveZeroes(shorts, pos); + if (consecutiveZeroesAtCurrentPos > longestConsecutiveZeroes) + { + longestConsecutiveZeroes = consecutiveZeroesAtCurrentPos; + longestConsecutiveZeroesPos = pos; + } + } + + return new int[]{longestConsecutiveZeroesPos, longestConsecutiveZeroes}; + } + + private int countConsecutiveZeroes(short[] shorts, int offset) + { + int count = 0; + for (int i = offset; i < shorts.length && shorts[i] == 0; i++) + { + count++; + } + + return count; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..edf129a --- /dev/null +++ b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,126 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..77b9a0f --- /dev/null +++ b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,483 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..309335e --- /dev/null +++ b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,232 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + /** + * The natural order of {@link com.googlecode.ipv6.IPv6AddressRange}s orders them on increasing first addresses, and on increasing last + * address if the first address would be equal. + *

+ * Note that the natural order does thus not compare sizes of ranges. + * + * @param that range to compare with + * @return negative, zero or positive depending on whether this is smaller, equal or greater than that + */ + @Override + public int compareTo(IPv6AddressRange that) + { + if (!this.first.equals(that.first)) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + return current = current.add(1); + else + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..60aa407 --- /dev/null +++ b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,149 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } +} diff --git a/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..66268ed --- /dev/null +++ b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = bitSetOf(first.getLowBits(), first.getHighBits()); + final BitSet lastBits = bitSetOf(last.getLowBits(), last.getHighBits()); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..ee4394b --- /dev/null +++ b/tags/java-ipv6-0.11/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,150 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength < 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval [0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = bitSetOf(addressToValidate.getLowBits(), addressToValidate.getHighBits()); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..834d561 --- /dev/null +++ b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,274 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..e699741 --- /dev/null +++ b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,135 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import junit.framework.Assert; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + IPv6AddressRange.fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + + @Test + public void compareTo() + { + final IPv6AddressRange a = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange b = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange c = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange d = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + + Assert.assertTrue(a.compareTo(b) > 0); + Assert.assertTrue(a.compareTo(c) < 0); + Assert.assertTrue(a.compareTo(d) < 0); + Assert.assertTrue(b.compareTo(c) < 0); + Assert.assertTrue(b.compareTo(d) < 0); + Assert.assertTrue(c.compareTo(d) > 0); + + Assert.assertTrue(a.compareTo(a) == 0); + Assert.assertTrue(b.compareTo(b) == 0); + Assert.assertTrue(c.compareTo(c) == 0); + Assert.assertTrue(d.compareTo(d) == 0); + } +} diff --git a/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..38c8a2e --- /dev/null +++ b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,325 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void constructFromByteArray() throws UnknownHostException + { + assertEquals("1:1:1:1:1:1:1:1", + IPv6Address.fromByteArray( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}) + .toString()); + } + + @Test + public void convertToByteArray() throws UnknownHostException + { + assertArrayEquals( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}, + IPv6Address.fromString("1:1:1:1:1:1:1:1").toByteArray()); + } + + @Test + public void convertToAndFromByteArray() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + byte[] randomBytes = new byte[16]; + rg.nextBytes(randomBytes); + + final IPv6Address address = IPv6Address.fromByteArray(randomBytes); + assertArrayEquals(randomBytes, address.toByteArray()); + } + } + + @Test + public void positionOfLongestRunOfZeroes() + { + assertArrayEquals(new int[]{0, 8}, fromString("::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{3, 5}, fromString("a:b:c::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{2, 5}, fromString("a:b::c").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{4, 4}, fromString("a:0:0:c::").startAndLengthOfLongestRunOfZeroes()); + } + + @Test + public void toStringCompactsLongestRunOfZeroes() + { + assertEquals("0:0:1::", fromString("0:0:1::").toString()); // and not ::1:0:0:0:0:0 + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + +} diff --git a/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..960d630 --- /dev/null +++ b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..0eea592 --- /dev/null +++ b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Negative() + { + new IPv6NetworkMask(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..a40b1bb --- /dev/null +++ b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + + @Test + public void contains() + { + assertTrue(IPv6Network.fromString("ffff::/8").contains(IPv6Address.fromString("ffff::1"))); + assertTrue(IPv6Network.fromString("1234:5678:1234:5678::/64").contains(IPv6Address.fromString("1234:5678:1234:5678:1::"))); + } + + @Test + public void zeroNetworkContainsEverything() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + + assertTrue(IPv6Network.fromString("::/0").contains(randomAddress)); + assertTrue(IPv6Network.fromString("abcd:effe:dcba::/0").contains(randomAddress)); + } +} diff --git a/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..380dc60 --- /dev/null +++ b/tags/java-ipv6-0.11/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,113 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.12/LICENSE b/tags/java-ipv6-0.12/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/tags/java-ipv6-0.12/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/tags/java-ipv6-0.12/NOTICE b/tags/java-ipv6-0.12/NOTICE new file mode 100644 index 0000000..a4605c4 --- /dev/null +++ b/tags/java-ipv6-0.12/NOTICE @@ -0,0 +1,2 @@ + Java IPv6 + Copyright 2013 Jan Van Besien \ No newline at end of file diff --git a/tags/java-ipv6-0.12/pom.xml b/tags/java-ipv6-0.12/pom.xml new file mode 100644 index 0000000..75028ef --- /dev/null +++ b/tags/java-ipv6-0.12/pom.xml @@ -0,0 +1,143 @@ + + + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.12 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.12 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.12 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.12 + + + + + junit + junit + 4.10 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + ${basedir} + false + + LICENSE + NOTICE + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/BitSetHelpers.java b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/BitSetHelpers.java new file mode 100644 index 0000000..698c51e --- /dev/null +++ b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/BitSetHelpers.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + * method. However, for java-6 compatibility, we go this way. + * + * @author Jan Van Besien + */ +class BitSetHelpers +{ + static BitSet bitSetOf(long lowerBits, long upperBits) + { + final BitSet bitSet = new BitSet(); + convert(lowerBits, 0, bitSet); + convert(upperBits, Long.SIZE, bitSet); + return bitSet; + } + + static void convert(long value, int bitSetOffset, BitSet bits) + { + int index = 0; + while (value != 0L) + { + if (value % 2L != 0) + { + bits.set(bitSetOffset + index); + } + ++index; + value = value >>> 1; + } + } + +} diff --git a/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..056114c --- /dev/null +++ b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,534 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.LongBuffer; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private static final int N_BYTES = 16; + + private final long highBits; + + private final long lowBits; + + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + * IPv6Addresses from a {@link String} or an {@link java.net.InetAddress}. The internal representation of an IPv6Address is exactly + * these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + public static IPv6Address fromLongs(long highBits, long lowBits) + { + return new IPv6Address(highBits, lowBits); + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". IPv4-Mapped IPv6 addresses such as "::ffff:123.456.123.456" are also supported. + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String withoutIPv4MappedNotation = IPv6AddressHelpers.rewriteIPv4MappedNotation(string); + final String longNotation = IPv6AddressHelpers.expandShortNotation(withoutIPv4MappedNotation); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Create an IPv6 address from a byte array. + * + * @param bytes byte array with 16 bytes + * @return IPv6 address + */ + public static IPv6Address fromByteArray(final byte[] bytes) + { + if (bytes == null) + throw new IllegalArgumentException("can not construct from [null]"); + if (bytes.length != N_BYTES) + throw new IllegalArgumentException("the byte array to construct from should be 16 bytes long"); + + ByteBuffer buf = ByteBuffer.allocate(N_BYTES); + for (byte b : bytes) + { + buf.put(b); + } + + buf.rewind(); + LongBuffer longBuffer = buf.asLongBuffer(); + return new IPv6Address(longBuffer.get(), longBuffer.get()); + } + + public byte[] toByteArray() + { + ByteBuffer byteBuffer = ByteBuffer.allocate(N_BYTES).putLong(highBits).putLong(lowBits); + return byteBuffer.array(); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something positive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() == 0) + { + return new IPv6Address(0, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * Returns true if the address is an IPv4-mapped IPv6 address. In these addresses, the first 80 bits are zero, the next 16 bits are one, + * and the remaining 32 bits are the IPv4 address. + * + * @return true if the address is an IPv4-mapped IPv6 addresses. + */ + public boolean isIPv4Mapped() + { + return this.highBits == 0 // 64 zero bits + && (this.lowBits & 0xFFFF000000000000L) == 0 // 16 more zero bits + && (this.lowBits & 0x0000FFFF00000000L) == 0x0000FFFF00000000L; // 16 one bits and the remainder is the IPv4 address + } + + /** + * @return true if the address is an IPv6 multicast address (an address in the network ff00::/8) + */ + public boolean isMulticast() + { + return IPv6Network.fromString("ff00::/8").contains(this); + } + + /** + * @return true if the address is an IPv6 site-local address (an address in the network fec0::/48) + */ + public boolean isSiteLocal() + { + return IPv6Network.fromString("fec0::/48").contains(this); + } + + /** + * @return true if the address is an IPv6 link-local address (an address in the network fe80::/48) + */ + public boolean isLinkLocal() + { + return IPv6Network.fromString("fe80::/64").contains(this); + } + + /** + * Returns a string representation of the IPv6 address. It will use shorthand notation and special notation for IPv4-mapped IPv6 + * addresses whenever possible. + * + * @return String representation of the IPv6 address + */ + @Override + public String toString() + { + if (isIPv4Mapped()) + return toIPv4MappedAddressString(); + else + return toShortHandNotationString(); + } + + private String toIPv4MappedAddressString() + { + int byteZero = (int) ((this.lowBits & 0x00000000FF000000L) >> 24); + int byteOne = (int) ((this.lowBits & 0x0000000000FF0000L) >> 16); + int byteTwo = (int) ((this.lowBits & 0x000000000000FF00L) >> 8); + int byteThree = (int) ((this.lowBits & 0x00000000000000FFL)); + + final StringBuilder result = new StringBuilder("::ffff:"); + result.append(byteZero).append(".").append(byteOne).append(".").append(byteTwo).append(".").append(byteThree); + + return result.toString(); + } + + private String toShortHandNotationString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + int[] shortHandNotationPositionAndLength = startAndLengthOfLongestRunOfZeroes(); + int shortHandNotationPosition = shortHandNotationPositionAndLength[0]; + int shortHandNotationLength = shortHandNotationPositionAndLength[1]; + + boolean useShortHandNotation = shortHandNotationLength > 1; // RFC5952 recommends not to use shorthand notation for a single zero + + for (int i = 0; i < strings.length; i++) + { + if (useShortHandNotation && i == shortHandNotationPosition) + { + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(i > shortHandNotationPosition && i < shortHandNotationPosition + shortHandNotationLength)) + { + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + private short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + int[] startAndLengthOfLongestRunOfZeroes() + { + int longestConsecutiveZeroes = 0; + int longestConsecutiveZeroesPos = -1; + short[] shorts = toShortArray(); + for (int pos = 0; pos < shorts.length; pos++) + { + int consecutiveZeroesAtCurrentPos = countConsecutiveZeroes(shorts, pos); + if (consecutiveZeroesAtCurrentPos > longestConsecutiveZeroes) + { + longestConsecutiveZeroes = consecutiveZeroesAtCurrentPos; + longestConsecutiveZeroesPos = pos; + } + } + + return new int[]{longestConsecutiveZeroesPos, longestConsecutiveZeroes}; + } + + private int countConsecutiveZeroes(short[] shorts, int offset) + { + int count = 0; + for (int i = offset; i < shorts.length && shorts[i] == 0; i++) + { + count++; + } + + return count; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..1e4784f --- /dev/null +++ b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,168 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.Arrays; +import java.util.regex.Pattern; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + private static final Pattern DOT_DELIM = Pattern.compile("\\."); + + /** + * Replaces a w.x.y.z substring at the end of the given string with corresponding hexadecimal notation. This is useful in case the + * string was using IPv4-Mapped address notation. + */ + static String rewriteIPv4MappedNotation(String string) + { + if (!string.contains(".")) + { + return string; + } + else + { + int lastColon = string.lastIndexOf(":"); + String firstPart = string.substring(0, lastColon + 1); + String mappedIPv4Part = string.substring(lastColon + 1); + + if (mappedIPv4Part.contains(".")) + { + String[] dotSplits = DOT_DELIM.split(mappedIPv4Part); + if (dotSplits.length != 4) + throw new IllegalArgumentException(String.format("can not parse [%s]", string)); + + StringBuilder rewrittenString = new StringBuilder(); + rewrittenString.append(firstPart); + int byteZero = Integer.parseInt(dotSplits[0]); + int byteOne = Integer.parseInt(dotSplits[1]); + int byteTwo = Integer.parseInt(dotSplits[2]); + int byteThree = Integer.parseInt(dotSplits[3]); + + rewrittenString.append(String.format("%02x", byteZero)); + rewrittenString.append(String.format("%02x", byteOne)); + rewrittenString.append(":"); + rewrittenString.append(String.format("%02x", byteTwo)); + rewrittenString.append(String.format("%02x", byteThree)); + + return rewrittenString.toString(); + } + else + { + throw new IllegalArgumentException(String.format("can not parse [%s]", string)); + } + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..77b9a0f --- /dev/null +++ b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,483 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..309335e --- /dev/null +++ b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,232 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + /** + * The natural order of {@link com.googlecode.ipv6.IPv6AddressRange}s orders them on increasing first addresses, and on increasing last + * address if the first address would be equal. + *

+ * Note that the natural order does thus not compare sizes of ranges. + * + * @param that range to compare with + * @return negative, zero or positive depending on whether this is smaller, equal or greater than that + */ + @Override + public int compareTo(IPv6AddressRange that) + { + if (!this.first.equals(that.first)) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + return current = current.add(1); + else + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..60aa407 --- /dev/null +++ b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,149 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } +} diff --git a/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..66268ed --- /dev/null +++ b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = bitSetOf(first.getLowBits(), first.getHighBits()); + final BitSet lastBits = bitSetOf(last.getLowBits(), last.getHighBits()); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..ee4394b --- /dev/null +++ b/tags/java-ipv6-0.12/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,150 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength < 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval [0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = bitSetOf(addressToValidate.getLowBits(), addressToValidate.getHighBits()); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..834d561 --- /dev/null +++ b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,274 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..e699741 --- /dev/null +++ b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,135 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import junit.framework.Assert; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + IPv6AddressRange.fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + + @Test + public void compareTo() + { + final IPv6AddressRange a = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange b = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange c = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange d = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + + Assert.assertTrue(a.compareTo(b) > 0); + Assert.assertTrue(a.compareTo(c) < 0); + Assert.assertTrue(a.compareTo(d) < 0); + Assert.assertTrue(b.compareTo(c) < 0); + Assert.assertTrue(b.compareTo(d) < 0); + Assert.assertTrue(c.compareTo(d) > 0); + + Assert.assertTrue(a.compareTo(a) == 0); + Assert.assertTrue(b.compareTo(b) == 0); + Assert.assertTrue(c.compareTo(c) == 0); + Assert.assertTrue(d.compareTo(d) == 0); + } +} diff --git a/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..3536ec3 --- /dev/null +++ b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,390 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesFromRFC5952() + { + assertEquals("::", fromString("::").toString()); + assertEquals("1:2:3:4::", fromString("1:2:3:4::").toString()); + assertEquals("::1:2:3:4", fromString("::1:2:3:4").toString()); + assertEquals("1::2", fromString("1::2").toString()); + assertEquals("::2", fromString("::2").toString()); + assertEquals("1::", fromString("1::").toString()); + assertEquals("a31:200:3abc::de4", fromString("0a31:0200:3AbC::0dE4").toString()); + assertEquals("1::4:0:0:0", fromString("1:0:0:0:4:0:0:0").toString()); + + assertEquals("2001:db8::1", fromString("2001:db8::1").toString()); + assertEquals("2001:db8::2:1", fromString("2001:db8:0:0:0:0:2:1").toString()); + assertEquals("2001:db8:0:1:1:1:1:1", fromString("2001:db8:0:1:1:1:1:1").toString()); + assertEquals("2001:db8::1:0:0:1", fromString("2001:db8::1:0:0:1").toString()); + assertEquals("2001:0:0:1::1", fromString("2001:0:0:1:0:0:0:1").toString()); + + assertEquals("1:0:0:4::", fromString("1:0:0:4::").toString()); + } + + @Test + public void parseSomeRealIPv4MappedAddresses() + { + assertEquals("::ffff:0.0.0.1", fromString("::ffff:0.0.0.1").toString()); + assertEquals("::ffff:192.168.139.50", fromString("::ffff:192.168.139.50").toString()); + assertEquals("::ffff:192.168.139.50", fromString("::ffff:c0a8:8b32").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void constructFromByteArray() throws UnknownHostException + { + assertEquals("1:1:1:1:1:1:1:1", + IPv6Address.fromByteArray( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}) + .toString()); + } + + @Test + public void convertToByteArray() throws UnknownHostException + { + assertArrayEquals( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}, + fromString("1:1:1:1:1:1:1:1").toByteArray()); + } + + @Test + public void convertToAndFromByteArray() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + byte[] randomBytes = new byte[16]; + rg.nextBytes(randomBytes); + + final IPv6Address address = IPv6Address.fromByteArray(randomBytes); + assertArrayEquals(randomBytes, address.toByteArray()); + } + } + + @Test + public void positionOfLongestRunOfZeroes() + { + assertArrayEquals(new int[]{0, 8}, fromString("::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{3, 5}, fromString("a:b:c::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{2, 5}, fromString("a:b::c").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{4, 4}, fromString("a:0:0:c::").startAndLengthOfLongestRunOfZeroes()); + } + + @Test + public void toStringCompactsLongestRunOfZeroes() + { + assertEquals("0:0:1::", fromString("0:0:1::").toString()); // and not ::1:0:0:0:0:0 + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + + @Test + public void isIPv4Mapped() + { + assertFalse(fromString("::").isIPv4Mapped()); + assertFalse(fromString("::0001:ffff:1234:5678").isIPv4Mapped()); + assertFalse(fromString("1::ffff:1234:5678").isIPv4Mapped()); + assertFalse(fromString("::afff:1234:5678").isIPv4Mapped()); + + assertTrue(fromString("::ffff:1234:5678").isIPv4Mapped()); + assertTrue(fromString("::ffff:192.168.123.123").isIPv4Mapped()); + } + + @Test + public void isMulticast() + { + assertFalse(fromString("::").isMulticast()); + + assertTrue(fromString("ff12::ffff:1234:5678").isMulticast()); + } + + @Test + public void isLinkLocal() + { + assertFalse(fromString("::").isLinkLocal()); + + assertTrue(fromString("fe80::ffff:1234:5678").isLinkLocal()); + } + + @Test + public void isSiteLocal() + { + assertFalse(fromString("::").isSiteLocal()); + + assertTrue(fromString("fec0::ffff:1234:5678").isSiteLocal()); + } + +} diff --git a/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..960d630 --- /dev/null +++ b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..0eea592 --- /dev/null +++ b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Negative() + { + new IPv6NetworkMask(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..a40b1bb --- /dev/null +++ b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + + @Test + public void contains() + { + assertTrue(IPv6Network.fromString("ffff::/8").contains(IPv6Address.fromString("ffff::1"))); + assertTrue(IPv6Network.fromString("1234:5678:1234:5678::/64").contains(IPv6Address.fromString("1234:5678:1234:5678:1::"))); + } + + @Test + public void zeroNetworkContainsEverything() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + + assertTrue(IPv6Network.fromString("::/0").contains(randomAddress)); + assertTrue(IPv6Network.fromString("abcd:effe:dcba::/0").contains(randomAddress)); + } +} diff --git a/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..9a1d62b --- /dev/null +++ b/tags/java-ipv6-0.12/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,114 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address iPv4MappedIPv6Address = IPv6Address.fromString("::ffff:192.168.0.1"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.13/LICENSE b/tags/java-ipv6-0.13/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/tags/java-ipv6-0.13/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/tags/java-ipv6-0.13/NOTICE b/tags/java-ipv6-0.13/NOTICE new file mode 100644 index 0000000..a4605c4 --- /dev/null +++ b/tags/java-ipv6-0.13/NOTICE @@ -0,0 +1,2 @@ + Java IPv6 + Copyright 2013 Jan Van Besien \ No newline at end of file diff --git a/tags/java-ipv6-0.13/pom.xml b/tags/java-ipv6-0.13/pom.xml new file mode 100644 index 0000000..a1a0b05 --- /dev/null +++ b/tags/java-ipv6-0.13/pom.xml @@ -0,0 +1,143 @@ + + + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.13 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.13 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.13 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.13 + + + + + junit + junit + 4.10 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + ${basedir} + false + + LICENSE + NOTICE + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/BitSetHelpers.java b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/BitSetHelpers.java new file mode 100644 index 0000000..698c51e --- /dev/null +++ b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/BitSetHelpers.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + * method. However, for java-6 compatibility, we go this way. + * + * @author Jan Van Besien + */ +class BitSetHelpers +{ + static BitSet bitSetOf(long lowerBits, long upperBits) + { + final BitSet bitSet = new BitSet(); + convert(lowerBits, 0, bitSet); + convert(upperBits, Long.SIZE, bitSet); + return bitSet; + } + + static void convert(long value, int bitSetOffset, BitSet bits) + { + int index = 0; + while (value != 0L) + { + if (value % 2L != 0) + { + bits.set(bitSetOffset + index); + } + ++index; + value = value >>> 1; + } + } + +} diff --git a/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..2954782 --- /dev/null +++ b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,534 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.LongBuffer; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private static final int N_BYTES = 16; + + private final long highBits; + + private final long lowBits; + + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + * IPv6Addresses from a {@link String} or an {@link java.net.InetAddress}. The internal representation of an IPv6Address is exactly + * these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + public static IPv6Address fromLongs(long highBits, long lowBits) + { + return new IPv6Address(highBits, lowBits); + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". IPv4-Mapped IPv6 addresses such as "::ffff:123.456.123.456" are also supported. + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String withoutIPv4MappedNotation = IPv6AddressHelpers.rewriteIPv4MappedNotation(string); + final String longNotation = IPv6AddressHelpers.expandShortNotation(withoutIPv4MappedNotation); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Create an IPv6 address from a byte array. + * + * @param bytes byte array with 16 bytes + * @return IPv6 address + */ + public static IPv6Address fromByteArray(final byte[] bytes) + { + if (bytes == null) + throw new IllegalArgumentException("can not construct from [null]"); + if (bytes.length != N_BYTES) + throw new IllegalArgumentException("the byte array to construct from should be 16 bytes long"); + + ByteBuffer buf = ByteBuffer.allocate(N_BYTES); + for (byte b : bytes) + { + buf.put(b); + } + + buf.rewind(); + LongBuffer longBuffer = buf.asLongBuffer(); + return new IPv6Address(longBuffer.get(), longBuffer.get()); + } + + public byte[] toByteArray() + { + ByteBuffer byteBuffer = ByteBuffer.allocate(N_BYTES).putLong(highBits).putLong(lowBits); + return byteBuffer.array(); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something positive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() == 0) + { + return new IPv6Address(0, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * Returns true if the address is an IPv4-mapped IPv6 address. In these addresses, the first 80 bits are zero, the next 16 bits are one, + * and the remaining 32 bits are the IPv4 address. + * + * @return true if the address is an IPv4-mapped IPv6 addresses. + */ + public boolean isIPv4Mapped() + { + return this.highBits == 0 // 64 zero bits + && (this.lowBits & 0xFFFF000000000000L) == 0 // 16 more zero bits + && (this.lowBits & 0x0000FFFF00000000L) == 0x0000FFFF00000000L; // 16 one bits and the remainder is the IPv4 address + } + + /** + * @return true if the address is an IPv6 multicast address (an address in the network ff00::/8) + */ + public boolean isMulticast() + { + return IPv6Network.MULTICAST_NETWORK.contains(this); + } + + /** + * @return true if the address is an IPv6 site-local address (an address in the network fec0::/48) + */ + public boolean isSiteLocal() + { + return IPv6Network.SITE_LOCAL_NETWORK.contains(this); + } + + /** + * @return true if the address is an IPv6 link-local address (an address in the network fe80::/48) + */ + public boolean isLinkLocal() + { + return IPv6Network.LINK_LOCAL_NETWORK.contains(this); + } + + /** + * Returns a string representation of the IPv6 address. It will use shorthand notation and special notation for IPv4-mapped IPv6 + * addresses whenever possible. + * + * @return String representation of the IPv6 address + */ + @Override + public String toString() + { + if (isIPv4Mapped()) + return toIPv4MappedAddressString(); + else + return toShortHandNotationString(); + } + + private String toIPv4MappedAddressString() + { + int byteZero = (int) ((this.lowBits & 0x00000000FF000000L) >> 24); + int byteOne = (int) ((this.lowBits & 0x0000000000FF0000L) >> 16); + int byteTwo = (int) ((this.lowBits & 0x000000000000FF00L) >> 8); + int byteThree = (int) ((this.lowBits & 0x00000000000000FFL)); + + final StringBuilder result = new StringBuilder("::ffff:"); + result.append(byteZero).append(".").append(byteOne).append(".").append(byteTwo).append(".").append(byteThree); + + return result.toString(); + } + + private String toShortHandNotationString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + int[] shortHandNotationPositionAndLength = startAndLengthOfLongestRunOfZeroes(); + int shortHandNotationPosition = shortHandNotationPositionAndLength[0]; + int shortHandNotationLength = shortHandNotationPositionAndLength[1]; + + boolean useShortHandNotation = shortHandNotationLength > 1; // RFC5952 recommends not to use shorthand notation for a single zero + + for (int i = 0; i < strings.length; i++) + { + if (useShortHandNotation && i == shortHandNotationPosition) + { + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(i > shortHandNotationPosition && i < shortHandNotationPosition + shortHandNotationLength)) + { + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + private short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + int[] startAndLengthOfLongestRunOfZeroes() + { + int longestConsecutiveZeroes = 0; + int longestConsecutiveZeroesPos = -1; + short[] shorts = toShortArray(); + for (int pos = 0; pos < shorts.length; pos++) + { + int consecutiveZeroesAtCurrentPos = countConsecutiveZeroes(shorts, pos); + if (consecutiveZeroesAtCurrentPos > longestConsecutiveZeroes) + { + longestConsecutiveZeroes = consecutiveZeroesAtCurrentPos; + longestConsecutiveZeroesPos = pos; + } + } + + return new int[]{longestConsecutiveZeroesPos, longestConsecutiveZeroes}; + } + + private int countConsecutiveZeroes(short[] shorts, int offset) + { + int count = 0; + for (int i = offset; i < shorts.length && shorts[i] == 0; i++) + { + count++; + } + + return count; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..1e4784f --- /dev/null +++ b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,168 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.Arrays; +import java.util.regex.Pattern; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + private static final Pattern DOT_DELIM = Pattern.compile("\\."); + + /** + * Replaces a w.x.y.z substring at the end of the given string with corresponding hexadecimal notation. This is useful in case the + * string was using IPv4-Mapped address notation. + */ + static String rewriteIPv4MappedNotation(String string) + { + if (!string.contains(".")) + { + return string; + } + else + { + int lastColon = string.lastIndexOf(":"); + String firstPart = string.substring(0, lastColon + 1); + String mappedIPv4Part = string.substring(lastColon + 1); + + if (mappedIPv4Part.contains(".")) + { + String[] dotSplits = DOT_DELIM.split(mappedIPv4Part); + if (dotSplits.length != 4) + throw new IllegalArgumentException(String.format("can not parse [%s]", string)); + + StringBuilder rewrittenString = new StringBuilder(); + rewrittenString.append(firstPart); + int byteZero = Integer.parseInt(dotSplits[0]); + int byteOne = Integer.parseInt(dotSplits[1]); + int byteTwo = Integer.parseInt(dotSplits[2]); + int byteThree = Integer.parseInt(dotSplits[3]); + + rewrittenString.append(String.format("%02x", byteZero)); + rewrittenString.append(String.format("%02x", byteOne)); + rewrittenString.append(":"); + rewrittenString.append(String.format("%02x", byteTwo)); + rewrittenString.append(String.format("%02x", byteThree)); + + return rewrittenString.toString(); + } + else + { + throw new IllegalArgumentException(String.format("can not parse [%s]", string)); + } + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..77b9a0f --- /dev/null +++ b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,483 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..6d2a925 --- /dev/null +++ b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,238 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + /** + * The natural order of {@link com.googlecode.ipv6.IPv6AddressRange}s orders them on increasing first addresses, and on increasing last + * address if the first address would be equal. + *

+ * Note that the natural order does thus not compare sizes of ranges. + * + * @param that range to compare with + * @return negative, zero or positive depending on whether this is smaller, equal or greater than that + */ + @Override + public int compareTo(IPv6AddressRange that) + { + if (!this.first.equals(that.first)) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + { + IPv6Address result = current; + current = current.add(1); + return result; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..49f23b0 --- /dev/null +++ b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,156 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + public static final IPv6Network MULTICAST_NETWORK = fromString("ff00::/8"); + + public static final IPv6Network SITE_LOCAL_NETWORK = fromString("fec0::/48"); + + public static final IPv6Network LINK_LOCAL_NETWORK = fromString("fe80::/64"); + + + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } +} diff --git a/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..66268ed --- /dev/null +++ b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = bitSetOf(first.getLowBits(), first.getHighBits()); + final BitSet lastBits = bitSetOf(last.getLowBits(), last.getHighBits()); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..ee4394b --- /dev/null +++ b/tags/java-ipv6-0.13/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,150 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength < 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval [0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = bitSetOf(addressToValidate.getLowBits(), addressToValidate.getHighBits()); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..834d561 --- /dev/null +++ b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,274 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..e699741 --- /dev/null +++ b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,135 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import junit.framework.Assert; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + IPv6AddressRange.fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + + @Test + public void compareTo() + { + final IPv6AddressRange a = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange b = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange c = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange d = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + + Assert.assertTrue(a.compareTo(b) > 0); + Assert.assertTrue(a.compareTo(c) < 0); + Assert.assertTrue(a.compareTo(d) < 0); + Assert.assertTrue(b.compareTo(c) < 0); + Assert.assertTrue(b.compareTo(d) < 0); + Assert.assertTrue(c.compareTo(d) > 0); + + Assert.assertTrue(a.compareTo(a) == 0); + Assert.assertTrue(b.compareTo(b) == 0); + Assert.assertTrue(c.compareTo(c) == 0); + Assert.assertTrue(d.compareTo(d) == 0); + } +} diff --git a/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..3536ec3 --- /dev/null +++ b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,390 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesFromRFC5952() + { + assertEquals("::", fromString("::").toString()); + assertEquals("1:2:3:4::", fromString("1:2:3:4::").toString()); + assertEquals("::1:2:3:4", fromString("::1:2:3:4").toString()); + assertEquals("1::2", fromString("1::2").toString()); + assertEquals("::2", fromString("::2").toString()); + assertEquals("1::", fromString("1::").toString()); + assertEquals("a31:200:3abc::de4", fromString("0a31:0200:3AbC::0dE4").toString()); + assertEquals("1::4:0:0:0", fromString("1:0:0:0:4:0:0:0").toString()); + + assertEquals("2001:db8::1", fromString("2001:db8::1").toString()); + assertEquals("2001:db8::2:1", fromString("2001:db8:0:0:0:0:2:1").toString()); + assertEquals("2001:db8:0:1:1:1:1:1", fromString("2001:db8:0:1:1:1:1:1").toString()); + assertEquals("2001:db8::1:0:0:1", fromString("2001:db8::1:0:0:1").toString()); + assertEquals("2001:0:0:1::1", fromString("2001:0:0:1:0:0:0:1").toString()); + + assertEquals("1:0:0:4::", fromString("1:0:0:4::").toString()); + } + + @Test + public void parseSomeRealIPv4MappedAddresses() + { + assertEquals("::ffff:0.0.0.1", fromString("::ffff:0.0.0.1").toString()); + assertEquals("::ffff:192.168.139.50", fromString("::ffff:192.168.139.50").toString()); + assertEquals("::ffff:192.168.139.50", fromString("::ffff:c0a8:8b32").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void constructFromByteArray() throws UnknownHostException + { + assertEquals("1:1:1:1:1:1:1:1", + IPv6Address.fromByteArray( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}) + .toString()); + } + + @Test + public void convertToByteArray() throws UnknownHostException + { + assertArrayEquals( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}, + fromString("1:1:1:1:1:1:1:1").toByteArray()); + } + + @Test + public void convertToAndFromByteArray() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + byte[] randomBytes = new byte[16]; + rg.nextBytes(randomBytes); + + final IPv6Address address = IPv6Address.fromByteArray(randomBytes); + assertArrayEquals(randomBytes, address.toByteArray()); + } + } + + @Test + public void positionOfLongestRunOfZeroes() + { + assertArrayEquals(new int[]{0, 8}, fromString("::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{3, 5}, fromString("a:b:c::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{2, 5}, fromString("a:b::c").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{4, 4}, fromString("a:0:0:c::").startAndLengthOfLongestRunOfZeroes()); + } + + @Test + public void toStringCompactsLongestRunOfZeroes() + { + assertEquals("0:0:1::", fromString("0:0:1::").toString()); // and not ::1:0:0:0:0:0 + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + + @Test + public void isIPv4Mapped() + { + assertFalse(fromString("::").isIPv4Mapped()); + assertFalse(fromString("::0001:ffff:1234:5678").isIPv4Mapped()); + assertFalse(fromString("1::ffff:1234:5678").isIPv4Mapped()); + assertFalse(fromString("::afff:1234:5678").isIPv4Mapped()); + + assertTrue(fromString("::ffff:1234:5678").isIPv4Mapped()); + assertTrue(fromString("::ffff:192.168.123.123").isIPv4Mapped()); + } + + @Test + public void isMulticast() + { + assertFalse(fromString("::").isMulticast()); + + assertTrue(fromString("ff12::ffff:1234:5678").isMulticast()); + } + + @Test + public void isLinkLocal() + { + assertFalse(fromString("::").isLinkLocal()); + + assertTrue(fromString("fe80::ffff:1234:5678").isLinkLocal()); + } + + @Test + public void isSiteLocal() + { + assertFalse(fromString("::").isSiteLocal()); + + assertTrue(fromString("fec0::ffff:1234:5678").isSiteLocal()); + } + +} diff --git a/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..960d630 --- /dev/null +++ b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..0eea592 --- /dev/null +++ b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Negative() + { + new IPv6NetworkMask(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..da26678 --- /dev/null +++ b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,126 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Iterator; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + + @Test + public void contains() + { + assertTrue(IPv6Network.fromString("ffff::/8").contains(IPv6Address.fromString("ffff::1"))); + assertTrue(IPv6Network.fromString("1234:5678:1234:5678::/64").contains(IPv6Address.fromString("1234:5678:1234:5678:1::"))); + } + + @Test + public void zeroNetworkContainsEverything() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + + assertTrue(IPv6Network.fromString("::/0").contains(randomAddress)); + assertTrue(IPv6Network.fromString("abcd:effe:dcba::/0").contains(randomAddress)); + } + + @Test + public void iteratorShouldStartWithFirstAndEndWithLast() + { + IPv6Network ipv6Network = IPv6Network.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0000/126"); + Iterator iterator = ipv6Network.iterator(); + int i = 0; + for (; iterator.hasNext(); i++) + { + assertEquals(IPv6Address.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:000" + i), iterator.next()); + } + assertEquals(4, i); + } +} diff --git a/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..9a1d62b --- /dev/null +++ b/tags/java-ipv6-0.13/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,114 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address iPv4MappedIPv6Address = IPv6Address.fromString("::ffff:192.168.0.1"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.14/LICENSE b/tags/java-ipv6-0.14/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/tags/java-ipv6-0.14/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/tags/java-ipv6-0.14/NOTICE b/tags/java-ipv6-0.14/NOTICE new file mode 100644 index 0000000..a4605c4 --- /dev/null +++ b/tags/java-ipv6-0.14/NOTICE @@ -0,0 +1,2 @@ + Java IPv6 + Copyright 2013 Jan Van Besien \ No newline at end of file diff --git a/tags/java-ipv6-0.14/pom.xml b/tags/java-ipv6-0.14/pom.xml new file mode 100644 index 0000000..e278985 --- /dev/null +++ b/tags/java-ipv6-0.14/pom.xml @@ -0,0 +1,143 @@ + + + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.14 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.14 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.14 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.14 + + + + + junit + junit + 4.10 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + ${basedir} + false + + LICENSE + NOTICE + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/BitSetHelpers.java b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/BitSetHelpers.java new file mode 100644 index 0000000..698c51e --- /dev/null +++ b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/BitSetHelpers.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + * method. However, for java-6 compatibility, we go this way. + * + * @author Jan Van Besien + */ +class BitSetHelpers +{ + static BitSet bitSetOf(long lowerBits, long upperBits) + { + final BitSet bitSet = new BitSet(); + convert(lowerBits, 0, bitSet); + convert(upperBits, Long.SIZE, bitSet); + return bitSet; + } + + static void convert(long value, int bitSetOffset, BitSet bits) + { + int index = 0; + while (value != 0L) + { + if (value % 2L != 0) + { + bits.set(bitSetOffset + index); + } + ++index; + value = value >>> 1; + } + } + +} diff --git a/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..73b6e33 --- /dev/null +++ b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,602 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.math.BigInteger; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.LongBuffer; +import java.util.Arrays; + +import static com.googlecode.ipv6.IPv6AddressHelpers.prefixWithZeroBytes; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private static final int N_BYTES = 16; + + public static final IPv6Address MAX = IPv6Address.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); + + private final long highBits; + + private final long lowBits; + + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + * IPv6Addresses from a {@link String} or an {@link java.net.InetAddress}. The internal representation of an IPv6Address is exactly + * these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + public static IPv6Address fromLongs(long highBits, long lowBits) + { + return new IPv6Address(highBits, lowBits); + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". IPv4-Mapped IPv6 addresses such as "::ffff:123.456.123.456" are also supported. + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String withoutIPv4MappedNotation = IPv6AddressHelpers.rewriteIPv4MappedNotation(string); + final String longNotation = IPv6AddressHelpers.expandShortNotation(withoutIPv4MappedNotation); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Create an IPv6 address from a byte array. + * + * @param bytes byte array with 16 bytes (interpreted unsigned) + * @return IPv6 address + */ + public static IPv6Address fromByteArray(final byte[] bytes) + { + if (bytes == null) + throw new IllegalArgumentException("can not construct from [null]"); + if (bytes.length != N_BYTES) + throw new IllegalArgumentException("the byte array to construct from should be 16 bytes long"); + + ByteBuffer buf = ByteBuffer.allocate(N_BYTES); + for (byte b : bytes) + { + buf.put(b); + } + + buf.rewind(); + LongBuffer longBuffer = buf.asLongBuffer(); + return new IPv6Address(longBuffer.get(), longBuffer.get()); + } + + /** + * @return byte[] representation + */ + public byte[] toByteArray() + { + ByteBuffer byteBuffer = ByteBuffer.allocate(N_BYTES).putLong(highBits).putLong(lowBits); + return byteBuffer.array(); + } + + /** + * Create an IPv6 address from a (positive) {@link java.math.BigInteger}. The magnitude of the {@link java.math.BigInteger} represents + * the IPv6 address value. Or in other words, the {@link java.math.BigInteger} with value N defines the Nth possible IPv6 address. + * + * @param bigInteger {@link java.math.BigInteger} value + * @return IPv6 address + */ + public static IPv6Address fromBigInteger(final BigInteger bigInteger) + { + if (bigInteger == null) + throw new IllegalArgumentException("can not construct from [null]"); + if (bigInteger.compareTo(BigInteger.ZERO) < 0) + throw new IllegalArgumentException("can not construct from negative value"); + if (bigInteger.compareTo(MAX.toBigInteger()) > 0) + throw new IllegalArgumentException("bigInteger represents a value bigger than 2^128 - 1"); + + byte[] bytes = bigInteger.toByteArray(); + + if (bytes[0] == 0) + { + // a zero byte was added to represent the (always positive, hence zero) sign bit + return fromByteArray(prefixWithZeroBytes(Arrays.copyOfRange(bytes, 1, bytes.length), N_BYTES)); + } + else + { + return fromByteArray(prefixWithZeroBytes(bytes, N_BYTES)); + } + } + + /** + * @return {@link java.math.BigInteger} representation. The magnitude of the {@link java.math.BigInteger} represents the IPv6 address + * value. Or in other words, the {@link java.math.BigInteger} with value N defines the Nth possible IPv6 address. + */ + public BigInteger toBigInteger() + { + return new BigInteger(1, toByteArray()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something positive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() == 0) + { + return new IPv6Address(0, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * Set a bit in the address. + * + * @param bit to set (in the range [0, 127]) + * @return an address with the given bit set + */ + public IPv6Address setBit(final int bit) + { + if (bit < 0 || bit > 127) + throw new IllegalArgumentException("can only set bits in the interval [0, 127]"); + + if (bit < 64) + { + return new IPv6Address(this.highBits, this.lowBits | (1 << bit)); + } + else + { + return new IPv6Address(this.highBits | (1 << (bit - 64)), this.lowBits); + } + } + + /** + * Returns true if the address is an IPv4-mapped IPv6 address. In these addresses, the first 80 bits are zero, the next 16 bits are one, + * and the remaining 32 bits are the IPv4 address. + * + * @return true if the address is an IPv4-mapped IPv6 addresses. + */ + public boolean isIPv4Mapped() + { + return this.highBits == 0 // 64 zero bits + && (this.lowBits & 0xFFFF000000000000L) == 0 // 16 more zero bits + && (this.lowBits & 0x0000FFFF00000000L) == 0x0000FFFF00000000L; // 16 one bits and the remainder is the IPv4 address + } + + /** + * @return true if the address is an IPv6 multicast address (an address in the network ff00::/8) + */ + public boolean isMulticast() + { + return IPv6Network.MULTICAST_NETWORK.contains(this); + } + + /** + * @return true if the address is an IPv6 site-local address (an address in the network fec0::/48) + */ + public boolean isSiteLocal() + { + return IPv6Network.SITE_LOCAL_NETWORK.contains(this); + } + + /** + * @return true if the address is an IPv6 link-local address (an address in the network fe80::/48) + */ + public boolean isLinkLocal() + { + return IPv6Network.LINK_LOCAL_NETWORK.contains(this); + } + + /** + * Returns a string representation of the IPv6 address. It will use shorthand notation and special notation for IPv4-mapped IPv6 + * addresses whenever possible. + * + * @return String representation of the IPv6 address + */ + @Override + public String toString() + { + if (isIPv4Mapped()) + return toIPv4MappedAddressString(); + else + return toShortHandNotationString(); + } + + private String toIPv4MappedAddressString() + { + int byteZero = (int) ((this.lowBits & 0x00000000FF000000L) >> 24); + int byteOne = (int) ((this.lowBits & 0x0000000000FF0000L) >> 16); + int byteTwo = (int) ((this.lowBits & 0x000000000000FF00L) >> 8); + int byteThree = (int) ((this.lowBits & 0x00000000000000FFL)); + + final StringBuilder result = new StringBuilder("::ffff:"); + result.append(byteZero).append(".").append(byteOne).append(".").append(byteTwo).append(".").append(byteThree); + + return result.toString(); + } + + private String toShortHandNotationString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + int[] shortHandNotationPositionAndLength = startAndLengthOfLongestRunOfZeroes(); + int shortHandNotationPosition = shortHandNotationPositionAndLength[0]; + int shortHandNotationLength = shortHandNotationPositionAndLength[1]; + + boolean useShortHandNotation = shortHandNotationLength > 1; // RFC5952 recommends not to use shorthand notation for a single zero + + for (int i = 0; i < strings.length; i++) + { + if (useShortHandNotation && i == shortHandNotationPosition) + { + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(i > shortHandNotationPosition && i < shortHandNotationPosition + shortHandNotationLength)) + { + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + private short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + int[] startAndLengthOfLongestRunOfZeroes() + { + int longestConsecutiveZeroes = 0; + int longestConsecutiveZeroesPos = -1; + short[] shorts = toShortArray(); + for (int pos = 0; pos < shorts.length; pos++) + { + int consecutiveZeroesAtCurrentPos = countConsecutiveZeroes(shorts, pos); + if (consecutiveZeroesAtCurrentPos > longestConsecutiveZeroes) + { + longestConsecutiveZeroes = consecutiveZeroesAtCurrentPos; + longestConsecutiveZeroesPos = pos; + } + } + + return new int[]{longestConsecutiveZeroesPos, longestConsecutiveZeroes}; + } + + private int countConsecutiveZeroes(short[] shorts, int offset) + { + int count = 0; + for (int i = offset; i < shorts.length && shorts[i] == 0; i++) + { + count++; + } + + return count; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..8403cfe --- /dev/null +++ b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,175 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.Arrays; +import java.util.regex.Pattern; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + private static final Pattern DOT_DELIM = Pattern.compile("\\."); + + /** + * Replaces a w.x.y.z substring at the end of the given string with corresponding hexadecimal notation. This is useful in case the + * string was using IPv4-Mapped address notation. + */ + static String rewriteIPv4MappedNotation(String string) + { + if (!string.contains(".")) + { + return string; + } + else + { + int lastColon = string.lastIndexOf(":"); + String firstPart = string.substring(0, lastColon + 1); + String mappedIPv4Part = string.substring(lastColon + 1); + + if (mappedIPv4Part.contains(".")) + { + String[] dotSplits = DOT_DELIM.split(mappedIPv4Part); + if (dotSplits.length != 4) + throw new IllegalArgumentException(String.format("can not parse [%s]", string)); + + StringBuilder rewrittenString = new StringBuilder(); + rewrittenString.append(firstPart); + int byteZero = Integer.parseInt(dotSplits[0]); + int byteOne = Integer.parseInt(dotSplits[1]); + int byteTwo = Integer.parseInt(dotSplits[2]); + int byteThree = Integer.parseInt(dotSplits[3]); + + rewrittenString.append(String.format("%02x", byteZero)); + rewrittenString.append(String.format("%02x", byteOne)); + rewrittenString.append(":"); + rewrittenString.append(String.format("%02x", byteTwo)); + rewrittenString.append(String.format("%02x", byteThree)); + + return rewrittenString.toString(); + } + else + { + throw new IllegalArgumentException(String.format("can not parse [%s]", string)); + } + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } + + static byte[] prefixWithZeroBytes(byte[] original, int newSize) + { + byte[] target = new byte[newSize]; + System.arraycopy(original, 0, target, newSize - original.length, original.length); + return target; + } +} diff --git a/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..77b9a0f --- /dev/null +++ b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,483 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..0cd612b --- /dev/null +++ b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,248 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.math.BigInteger; +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + public BigInteger size() + { + BigInteger firstAsBigInteger = new BigInteger(1, first.toByteArray()); + BigInteger lastAsBigInteger = new BigInteger(1, last.toByteArray()); + + // note that first and last are included in the range. + return lastAsBigInteger.subtract(firstAsBigInteger).add(BigInteger.ONE); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + /** + * The natural order of {@link com.googlecode.ipv6.IPv6AddressRange}s orders them on increasing first addresses, and on increasing last + * address if the first address would be equal. + *

+ * Note that the natural order does thus not compare sizes of ranges. + * + * @param that range to compare with + * @return negative, zero or positive depending on whether this is smaller, equal or greater than that + */ + @Override + public int compareTo(IPv6AddressRange that) + { + if (!this.first.equals(that.first)) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + { + IPv6Address result = current; + current = current.add(1); + return result; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("This iterator provides read only access"); + } + } +} diff --git a/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..f40c5d0 --- /dev/null +++ b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,225 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.math.BigInteger; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + public static final IPv6Network MULTICAST_NETWORK = fromString("ff00::/8"); + + public static final IPv6Network SITE_LOCAL_NETWORK = fromString("fec0::/48"); + + public static final IPv6Network LINK_LOCAL_NETWORK = fromString("fe80::/64"); + + + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + /** + * Split a network in smaller subnets of a given size. + * + * @param size size (expressed as {@link com.googlecode.ipv6.IPv6NetworkMask}) of the subnets + * @return iterator of the splitted subnets. + * @throws IllegalArgumentException if the requested size is bigger than the original size + */ + public Iterator split(IPv6NetworkMask size) + { + if (size.asPrefixLength() < this.getNetmask().asPrefixLength()) + throw new IllegalArgumentException(String.format("Can not split a network of size %s in subnets of larger size %s", + this.getNetmask().asPrefixLength(), size.asPrefixLength())); + + return new IPv6NetworkSplitsIterator(size); + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } + + private final class IPv6NetworkSplitsIterator implements Iterator + { + private final IPv6NetworkMask size; + + private IPv6Network current; + + private BigInteger nbrAddressesPerSplit; + + public IPv6NetworkSplitsIterator(IPv6NetworkMask size) + { + this.size = size; + this.nbrAddressesPerSplit = BigInteger.ONE.shiftLeft(128 - size.asPrefixLength()); + this.current = IPv6Network.fromAddressAndMask(IPv6Network.this.address, size); + } + + @Override + public boolean hasNext() + { + return current.getLast().compareTo(IPv6Network.this.getLast()) <= 0; + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + IPv6Network result = current; + current = calculateNext(current); + return result; + } + else + { + throw new NoSuchElementException(); + } + } + + private IPv6Network calculateNext(IPv6Network current) + { + BigInteger next = current.address.toBigInteger().add(nbrAddressesPerSplit); + return IPv6Network.fromAddressAndMask(IPv6Address.fromBigInteger(next), size); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("This iterator provides read only access"); + } + } +} diff --git a/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..66268ed --- /dev/null +++ b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = bitSetOf(first.getLowBits(), first.getHighBits()); + final BitSet lastBits = bitSetOf(last.getLowBits(), last.getHighBits()); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..ee4394b --- /dev/null +++ b/tags/java-ipv6-0.14/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,150 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength < 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval [0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = bitSetOf(addressToValidate.getLowBits(), addressToValidate.getHighBits()); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..834d561 --- /dev/null +++ b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,274 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..9cd1473 --- /dev/null +++ b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,148 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import junit.framework.Assert; +import org.junit.Test; + +import java.math.BigInteger; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static com.googlecode.ipv6.IPv6AddressRange.fromFirstAndLast; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + + @Test + public void compareTo() + { + final IPv6AddressRange a = + fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange b = + fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange c = + fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange d = + fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + + Assert.assertTrue(a.compareTo(b) > 0); + Assert.assertTrue(a.compareTo(c) < 0); + Assert.assertTrue(a.compareTo(d) < 0); + Assert.assertTrue(b.compareTo(c) < 0); + Assert.assertTrue(b.compareTo(d) < 0); + Assert.assertTrue(c.compareTo(d) > 0); + + Assert.assertTrue(a.compareTo(a) == 0); + Assert.assertTrue(b.compareTo(b) == 0); + Assert.assertTrue(c.compareTo(c) == 0); + Assert.assertTrue(d.compareTo(d) == 0); + } + + @Test + public void size() + { + assertEquals(BigInteger.valueOf(11), fromFirstAndLast(fromString("::"), fromString("::a")).size()); + assertEquals(BigInteger.valueOf(131074), fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:5:5")).size()); + assertEquals(BigInteger.valueOf(2).pow(128), + fromFirstAndLast(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")).size()); + } + +} diff --git a/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..66798ac --- /dev/null +++ b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,427 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.math.BigInteger; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesFromRFC5952() + { + assertEquals("::", fromString("::").toString()); + assertEquals("1:2:3:4::", fromString("1:2:3:4::").toString()); + assertEquals("::1:2:3:4", fromString("::1:2:3:4").toString()); + assertEquals("1::2", fromString("1::2").toString()); + assertEquals("::2", fromString("::2").toString()); + assertEquals("1::", fromString("1::").toString()); + assertEquals("a31:200:3abc::de4", fromString("0a31:0200:3AbC::0dE4").toString()); + assertEquals("1::4:0:0:0", fromString("1:0:0:0:4:0:0:0").toString()); + + assertEquals("2001:db8::1", fromString("2001:db8::1").toString()); + assertEquals("2001:db8::2:1", fromString("2001:db8:0:0:0:0:2:1").toString()); + assertEquals("2001:db8:0:1:1:1:1:1", fromString("2001:db8:0:1:1:1:1:1").toString()); + assertEquals("2001:db8::1:0:0:1", fromString("2001:db8::1:0:0:1").toString()); + assertEquals("2001:0:0:1::1", fromString("2001:0:0:1:0:0:0:1").toString()); + + assertEquals("1:0:0:4::", fromString("1:0:0:4::").toString()); + } + + @Test + public void parseSomeRealIPv4MappedAddresses() + { + assertEquals("::ffff:0.0.0.1", fromString("::ffff:0.0.0.1").toString()); + assertEquals("::ffff:192.168.139.50", fromString("::ffff:192.168.139.50").toString()); + assertEquals("::ffff:192.168.139.50", fromString("::ffff:c0a8:8b32").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void constructFromByteArray() throws UnknownHostException + { + assertEquals("1:1:1:1:1:1:1:1", + IPv6Address.fromByteArray( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}) + .toString()); + } + + @Test + public void convertToByteArray() throws UnknownHostException + { + assertArrayEquals( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}, + fromString("1:1:1:1:1:1:1:1").toByteArray()); + } + + @Test + public void convertToAndFromByteArray() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + byte[] randomBytes = new byte[16]; + rg.nextBytes(randomBytes); + + final IPv6Address address = IPv6Address.fromByteArray(randomBytes); + assertArrayEquals(randomBytes, address.toByteArray()); + } + } + + @Test + public void convertToBigInteger() throws UnknownHostException + { + assertEquals(BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE), IPv6Address.MAX.toBigInteger()); + assertEquals(BigInteger.ONE.shiftLeft(128).subtract(BigInteger.valueOf(16)), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0").toBigInteger()); + } + + @Test + public void convertToAndFromBigInteger() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + byte[] randomBytes = new byte[16]; + rg.nextBytes(randomBytes); + BigInteger randomBigInteger = new BigInteger(1, randomBytes); + + final IPv6Address address = IPv6Address.fromBigInteger(randomBigInteger); + assertEquals(randomBigInteger, address.toBigInteger()); + } + } + + @Test + public void positionOfLongestRunOfZeroes() + { + assertArrayEquals(new int[]{0, 8}, fromString("::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{3, 5}, fromString("a:b:c::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{2, 5}, fromString("a:b::c").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{4, 4}, fromString("a:0:0:c::").startAndLengthOfLongestRunOfZeroes()); + } + + @Test + public void toStringCompactsLongestRunOfZeroes() + { + assertEquals("0:0:1::", fromString("0:0:1::").toString()); // and not ::1:0:0:0:0:0 + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void setBit() + { + assertEquals(fromString("::1"), fromString("::").setBit(0)); + assertEquals(fromString("::2"), fromString("::").setBit(1)); + assertEquals(fromString("::3"), fromString("::").setBit(0).setBit(1)); + + assertEquals(fromString("0:0:0:1::"), fromString("::").setBit(64)); + assertEquals(fromString("0:0:0:2::"), fromString("::").setBit(65)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + + @Test + public void isIPv4Mapped() + { + assertFalse(fromString("::").isIPv4Mapped()); + assertFalse(fromString("::0001:ffff:1234:5678").isIPv4Mapped()); + assertFalse(fromString("1::ffff:1234:5678").isIPv4Mapped()); + assertFalse(fromString("::afff:1234:5678").isIPv4Mapped()); + + assertTrue(fromString("::ffff:1234:5678").isIPv4Mapped()); + assertTrue(fromString("::ffff:192.168.123.123").isIPv4Mapped()); + } + + @Test + public void isMulticast() + { + assertFalse(fromString("::").isMulticast()); + + assertTrue(fromString("ff12::ffff:1234:5678").isMulticast()); + } + + @Test + public void isLinkLocal() + { + assertFalse(fromString("::").isLinkLocal()); + + assertTrue(fromString("fe80::ffff:1234:5678").isLinkLocal()); + } + + @Test + public void isSiteLocal() + { + assertFalse(fromString("::").isSiteLocal()); + + assertTrue(fromString("fec0::ffff:1234:5678").isSiteLocal()); + } + +} diff --git a/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..960d630 --- /dev/null +++ b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..0eea592 --- /dev/null +++ b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Negative() + { + new IPv6NetworkMask(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..21d9e61 --- /dev/null +++ b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,190 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Iterator; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + + @Test + public void contains() + { + assertTrue(IPv6Network.fromString("ffff::/8").contains(IPv6Address.fromString("ffff::1"))); + assertTrue(IPv6Network.fromString("1234:5678:1234:5678::/64").contains(IPv6Address.fromString("1234:5678:1234:5678:1::"))); + } + + @Test + public void zeroNetworkContainsEverything() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + + assertTrue(IPv6Network.fromString("::/0").contains(randomAddress)); + assertTrue(IPv6Network.fromString("abcd:effe:dcba::/0").contains(randomAddress)); + } + + @Test + public void iteratorShouldStartWithFirstAndEndWithLast() + { + IPv6Network ipv6Network = IPv6Network.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0000/126"); + Iterator iterator = ipv6Network.iterator(); + int i = 0; + for (; iterator.hasNext(); i++) + { + assertEquals(IPv6Address.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:000" + i), iterator.next()); + } + assertEquals(4, i); + } + + @Test + public void split() + { + { + IPv6Network slash120 = IPv6Network.fromString("::ffff:192.168.123.0/120"); + Iterator splits = slash120.split(IPv6NetworkMask.fromPrefixLength(121)); + verifySplits(splits, 2, IPv6Network.fromString("::ffff:192.168.123.0/121"), + IPv6Network.fromString("::ffff:192.168.123.128/121")); + } + + { + IPv6Network slash30 = IPv6Network.fromString("a:b:c:d:1:2:3:4/30"); // a:8:: is the host address after masking with /30 + Iterator splits = slash30.split(IPv6NetworkMask.fromPrefixLength(40)); + verifySplits(splits, (int) Math.pow(2, 40 - 30), + IPv6Network.fromString("a:8::/40"), + IPv6Network.fromString("a:8:100::/40"), + IPv6Network.fromString("a:8:200::/40")); + } + } + + @Test(expected = IllegalArgumentException.class) + public void splitInLargerSize() + { + IPv6Network ipv6Network = IPv6Network.fromString("1:2:3:4:5:6:7:8/69"); + ipv6Network.split(IPv6NetworkMask.fromPrefixLength(68)); // 68 subnet is bigger than 69 + } + + @Test + public void splitInSameSize() + { + IPv6Network ipv6Network = IPv6Network.fromString("1:2:3:4:5:6:7:8/69"); + Iterator splits = ipv6Network.split(IPv6NetworkMask.fromPrefixLength(69)); + verifySplits(splits, 1, ipv6Network); + } + + /** + * Verify a splitted network. + * + * @param splits splits to verify + * @param expectedNbr number of expected splits + * @param expectedSplits the first splits in the list to expect (check as many as you want but no need to check them all) + */ + private void verifySplits(Iterator splits, int expectedNbr, IPv6Network... expectedSplits) + { + int nChecked = 0; + + // check the ones that are explicitely passed + for (IPv6Network expectedSplit : expectedSplits) + { + assertEquals(expectedSplit, splits.next()); + nChecked++; + } + + // merely check count for the others + while (splits.hasNext()) + { + splits.next(); + nChecked++; + } + + assertEquals(expectedNbr, nChecked); + } + +} diff --git a/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..dbcee27 --- /dev/null +++ b/tags/java-ipv6-0.14/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,139 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +import java.util.Iterator; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address iPv4MappedIPv6Address = IPv6Address.fromString("::ffff:192.168.0.1"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test + public void ipNetworkSubnetCalculation() + { + final IPv6Network network = IPv6Network.fromString("1:2:3:4:5:6:7:0/120"); + + Iterator splits = network.split(IPv6NetworkMask.fromPrefixLength(124)); + while (splits.hasNext()) + System.out.println(splits.next()); + + // prints 1:2:3:4:5:6:7:0/124, 1:2:3:4:5:6:7:10/124, 1:2:3:4:5:6:7:20/124, ... until 1:2:3:4:5:6:7:f0/124 (16 in total) + } + + @Test + public void ipNetworkNotationChoices() + { + IPv6Network prefixLengthNotation = IPv6Network.fromString("::1/16"); + IPv6Network addressNotation = + IPv6Network.fromAddressAndMask(IPv6Address.fromString("::"), IPv6NetworkMask.fromAddress(IPv6Address.fromString("ffff::"))); + System.out.println(prefixLengthNotation.equals(addressNotation)); // prints true + System.out.println(prefixLengthNotation); // prints ::/16 + System.out.println(prefixLengthNotation.getFirst() + "/" + prefixLengthNotation.getNetmask().asAddress()); // prints ::/ffff:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.15/LICENSE b/tags/java-ipv6-0.15/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/tags/java-ipv6-0.15/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/tags/java-ipv6-0.15/NOTICE b/tags/java-ipv6-0.15/NOTICE new file mode 100644 index 0000000..a4605c4 --- /dev/null +++ b/tags/java-ipv6-0.15/NOTICE @@ -0,0 +1,2 @@ + Java IPv6 + Copyright 2013 Jan Van Besien \ No newline at end of file diff --git a/tags/java-ipv6-0.15/pom.xml b/tags/java-ipv6-0.15/pom.xml new file mode 100644 index 0000000..f79be15 --- /dev/null +++ b/tags/java-ipv6-0.15/pom.xml @@ -0,0 +1,149 @@ + + + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.15 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.15 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.15 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.15 + + + + + junit + junit + 4.10 + test + + + com.google.guava + guava + 14.0.1 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + ${basedir} + false + + LICENSE + NOTICE + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/BitSetHelpers.java b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/BitSetHelpers.java new file mode 100644 index 0000000..698c51e --- /dev/null +++ b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/BitSetHelpers.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + * method. However, for java-6 compatibility, we go this way. + * + * @author Jan Van Besien + */ +class BitSetHelpers +{ + static BitSet bitSetOf(long lowerBits, long upperBits) + { + final BitSet bitSet = new BitSet(); + convert(lowerBits, 0, bitSet); + convert(upperBits, Long.SIZE, bitSet); + return bitSet; + } + + static void convert(long value, int bitSetOffset, BitSet bits) + { + int index = 0; + while (value != 0L) + { + if (value % 2L != 0) + { + bits.set(bitSetOffset + index); + } + ++index; + value = value >>> 1; + } + } + +} diff --git a/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..73b6e33 --- /dev/null +++ b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,602 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.math.BigInteger; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.LongBuffer; +import java.util.Arrays; + +import static com.googlecode.ipv6.IPv6AddressHelpers.prefixWithZeroBytes; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private static final int N_BYTES = 16; + + public static final IPv6Address MAX = IPv6Address.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); + + private final long highBits; + + private final long lowBits; + + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + * IPv6Addresses from a {@link String} or an {@link java.net.InetAddress}. The internal representation of an IPv6Address is exactly + * these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + public static IPv6Address fromLongs(long highBits, long lowBits) + { + return new IPv6Address(highBits, lowBits); + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". IPv4-Mapped IPv6 addresses such as "::ffff:123.456.123.456" are also supported. + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String withoutIPv4MappedNotation = IPv6AddressHelpers.rewriteIPv4MappedNotation(string); + final String longNotation = IPv6AddressHelpers.expandShortNotation(withoutIPv4MappedNotation); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Create an IPv6 address from a byte array. + * + * @param bytes byte array with 16 bytes (interpreted unsigned) + * @return IPv6 address + */ + public static IPv6Address fromByteArray(final byte[] bytes) + { + if (bytes == null) + throw new IllegalArgumentException("can not construct from [null]"); + if (bytes.length != N_BYTES) + throw new IllegalArgumentException("the byte array to construct from should be 16 bytes long"); + + ByteBuffer buf = ByteBuffer.allocate(N_BYTES); + for (byte b : bytes) + { + buf.put(b); + } + + buf.rewind(); + LongBuffer longBuffer = buf.asLongBuffer(); + return new IPv6Address(longBuffer.get(), longBuffer.get()); + } + + /** + * @return byte[] representation + */ + public byte[] toByteArray() + { + ByteBuffer byteBuffer = ByteBuffer.allocate(N_BYTES).putLong(highBits).putLong(lowBits); + return byteBuffer.array(); + } + + /** + * Create an IPv6 address from a (positive) {@link java.math.BigInteger}. The magnitude of the {@link java.math.BigInteger} represents + * the IPv6 address value. Or in other words, the {@link java.math.BigInteger} with value N defines the Nth possible IPv6 address. + * + * @param bigInteger {@link java.math.BigInteger} value + * @return IPv6 address + */ + public static IPv6Address fromBigInteger(final BigInteger bigInteger) + { + if (bigInteger == null) + throw new IllegalArgumentException("can not construct from [null]"); + if (bigInteger.compareTo(BigInteger.ZERO) < 0) + throw new IllegalArgumentException("can not construct from negative value"); + if (bigInteger.compareTo(MAX.toBigInteger()) > 0) + throw new IllegalArgumentException("bigInteger represents a value bigger than 2^128 - 1"); + + byte[] bytes = bigInteger.toByteArray(); + + if (bytes[0] == 0) + { + // a zero byte was added to represent the (always positive, hence zero) sign bit + return fromByteArray(prefixWithZeroBytes(Arrays.copyOfRange(bytes, 1, bytes.length), N_BYTES)); + } + else + { + return fromByteArray(prefixWithZeroBytes(bytes, N_BYTES)); + } + } + + /** + * @return {@link java.math.BigInteger} representation. The magnitude of the {@link java.math.BigInteger} represents the IPv6 address + * value. Or in other words, the {@link java.math.BigInteger} with value N defines the Nth possible IPv6 address. + */ + public BigInteger toBigInteger() + { + return new BigInteger(1, toByteArray()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something positive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() == 0) + { + return new IPv6Address(0, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * Set a bit in the address. + * + * @param bit to set (in the range [0, 127]) + * @return an address with the given bit set + */ + public IPv6Address setBit(final int bit) + { + if (bit < 0 || bit > 127) + throw new IllegalArgumentException("can only set bits in the interval [0, 127]"); + + if (bit < 64) + { + return new IPv6Address(this.highBits, this.lowBits | (1 << bit)); + } + else + { + return new IPv6Address(this.highBits | (1 << (bit - 64)), this.lowBits); + } + } + + /** + * Returns true if the address is an IPv4-mapped IPv6 address. In these addresses, the first 80 bits are zero, the next 16 bits are one, + * and the remaining 32 bits are the IPv4 address. + * + * @return true if the address is an IPv4-mapped IPv6 addresses. + */ + public boolean isIPv4Mapped() + { + return this.highBits == 0 // 64 zero bits + && (this.lowBits & 0xFFFF000000000000L) == 0 // 16 more zero bits + && (this.lowBits & 0x0000FFFF00000000L) == 0x0000FFFF00000000L; // 16 one bits and the remainder is the IPv4 address + } + + /** + * @return true if the address is an IPv6 multicast address (an address in the network ff00::/8) + */ + public boolean isMulticast() + { + return IPv6Network.MULTICAST_NETWORK.contains(this); + } + + /** + * @return true if the address is an IPv6 site-local address (an address in the network fec0::/48) + */ + public boolean isSiteLocal() + { + return IPv6Network.SITE_LOCAL_NETWORK.contains(this); + } + + /** + * @return true if the address is an IPv6 link-local address (an address in the network fe80::/48) + */ + public boolean isLinkLocal() + { + return IPv6Network.LINK_LOCAL_NETWORK.contains(this); + } + + /** + * Returns a string representation of the IPv6 address. It will use shorthand notation and special notation for IPv4-mapped IPv6 + * addresses whenever possible. + * + * @return String representation of the IPv6 address + */ + @Override + public String toString() + { + if (isIPv4Mapped()) + return toIPv4MappedAddressString(); + else + return toShortHandNotationString(); + } + + private String toIPv4MappedAddressString() + { + int byteZero = (int) ((this.lowBits & 0x00000000FF000000L) >> 24); + int byteOne = (int) ((this.lowBits & 0x0000000000FF0000L) >> 16); + int byteTwo = (int) ((this.lowBits & 0x000000000000FF00L) >> 8); + int byteThree = (int) ((this.lowBits & 0x00000000000000FFL)); + + final StringBuilder result = new StringBuilder("::ffff:"); + result.append(byteZero).append(".").append(byteOne).append(".").append(byteTwo).append(".").append(byteThree); + + return result.toString(); + } + + private String toShortHandNotationString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + int[] shortHandNotationPositionAndLength = startAndLengthOfLongestRunOfZeroes(); + int shortHandNotationPosition = shortHandNotationPositionAndLength[0]; + int shortHandNotationLength = shortHandNotationPositionAndLength[1]; + + boolean useShortHandNotation = shortHandNotationLength > 1; // RFC5952 recommends not to use shorthand notation for a single zero + + for (int i = 0; i < strings.length; i++) + { + if (useShortHandNotation && i == shortHandNotationPosition) + { + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(i > shortHandNotationPosition && i < shortHandNotationPosition + shortHandNotationLength)) + { + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + private short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + int[] startAndLengthOfLongestRunOfZeroes() + { + int longestConsecutiveZeroes = 0; + int longestConsecutiveZeroesPos = -1; + short[] shorts = toShortArray(); + for (int pos = 0; pos < shorts.length; pos++) + { + int consecutiveZeroesAtCurrentPos = countConsecutiveZeroes(shorts, pos); + if (consecutiveZeroesAtCurrentPos > longestConsecutiveZeroes) + { + longestConsecutiveZeroes = consecutiveZeroesAtCurrentPos; + longestConsecutiveZeroesPos = pos; + } + } + + return new int[]{longestConsecutiveZeroesPos, longestConsecutiveZeroes}; + } + + private int countConsecutiveZeroes(short[] shorts, int offset) + { + int count = 0; + for (int i = offset; i < shorts.length && shorts[i] == 0; i++) + { + count++; + } + + return count; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..8403cfe --- /dev/null +++ b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,175 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.Arrays; +import java.util.regex.Pattern; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + private static final Pattern DOT_DELIM = Pattern.compile("\\."); + + /** + * Replaces a w.x.y.z substring at the end of the given string with corresponding hexadecimal notation. This is useful in case the + * string was using IPv4-Mapped address notation. + */ + static String rewriteIPv4MappedNotation(String string) + { + if (!string.contains(".")) + { + return string; + } + else + { + int lastColon = string.lastIndexOf(":"); + String firstPart = string.substring(0, lastColon + 1); + String mappedIPv4Part = string.substring(lastColon + 1); + + if (mappedIPv4Part.contains(".")) + { + String[] dotSplits = DOT_DELIM.split(mappedIPv4Part); + if (dotSplits.length != 4) + throw new IllegalArgumentException(String.format("can not parse [%s]", string)); + + StringBuilder rewrittenString = new StringBuilder(); + rewrittenString.append(firstPart); + int byteZero = Integer.parseInt(dotSplits[0]); + int byteOne = Integer.parseInt(dotSplits[1]); + int byteTwo = Integer.parseInt(dotSplits[2]); + int byteThree = Integer.parseInt(dotSplits[3]); + + rewrittenString.append(String.format("%02x", byteZero)); + rewrittenString.append(String.format("%02x", byteOne)); + rewrittenString.append(":"); + rewrittenString.append(String.format("%02x", byteTwo)); + rewrittenString.append(String.format("%02x", byteThree)); + + return rewrittenString.toString(); + } + else + { + throw new IllegalArgumentException(String.format("can not parse [%s]", string)); + } + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } + + static byte[] prefixWithZeroBytes(byte[] original, int newSize) + { + byte[] target = new byte[newSize]; + System.arraycopy(original, 0, target, newSize - original.length, original.length); + return target; + } +} diff --git a/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..77b9a0f --- /dev/null +++ b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,483 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..522a3e0 --- /dev/null +++ b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,316 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.math.BigInteger; +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new IPv6AddressRangeIterator(); + } + + /** + * @return number of addresses in the range + */ + public BigInteger size() + { + BigInteger firstAsBigInteger = new BigInteger(1, first.toByteArray()); + BigInteger lastAsBigInteger = new BigInteger(1, last.toByteArray()); + + // note that first and last are included in the range. + return lastAsBigInteger.subtract(firstAsBigInteger).add(BigInteger.ONE); + } + + /** + * Deaggregate a range of IPv6 addresses (which is not necessarily aligned with a single IPv6 network) into a minimal set of non + * overlapping consecutive subnets. + * + * @return iterator of IPv6 networks that all together define the minimal set of subnets by which the range can be represented. + */ + public Iterator toSubnets() + { + return new IPv6AddressRangeAsSubnetsIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + /** + * The natural order of {@link com.googlecode.ipv6.IPv6AddressRange}s orders them on increasing first addresses, and on increasing last + * address if the first address would be equal. + *

+ * Note that the natural order does thus not compare sizes of ranges. + * + * @param that range to compare with + * @return negative, zero or positive depending on whether this is smaller, equal or greater than that + */ + @Override + public int compareTo(IPv6AddressRange that) + { + if (!this.first.equals(that.first)) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class IPv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + { + IPv6Address result = current; + current = current.add(1); + return result; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("This iterator provides read only access"); + } + } + + private class IPv6AddressRangeAsSubnetsIterator implements Iterator + { + + private IPv6Address base = first; + private IPv6Network next; + + @Override + public IPv6Network next() + { + int step; + + if (hasNext()) + { + step = 0; + + // try setting the step-th bit until we reach a bit that is already set + while (!(base.setBit(step)).equals(base)) + { + // if the max address in this subnet is beyond the end of the range, we went too far + if ((base.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(127 - step)).compareTo(last) > 0)) + { + break; + } + step++; + } + + // the next subnet is found + next = IPv6Network.fromAddressAndMask(base, IPv6NetworkMask.fromPrefixLength(128 - step)); + + // start the next loop after the end of the subnet just found + base = next.getLast().add(1); + } + else + { + throw new NoSuchElementException(); + } + + return next; + } + + @Override + public boolean hasNext() + { + // there is a next subnet as long as we didn't reach the end of the range + return (base.compareTo(last) <= 0); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("This iterator provides read only access"); + } + } +} diff --git a/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..f40c5d0 --- /dev/null +++ b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,225 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.math.BigInteger; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + public static final IPv6Network MULTICAST_NETWORK = fromString("ff00::/8"); + + public static final IPv6Network SITE_LOCAL_NETWORK = fromString("fec0::/48"); + + public static final IPv6Network LINK_LOCAL_NETWORK = fromString("fe80::/64"); + + + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + /** + * Split a network in smaller subnets of a given size. + * + * @param size size (expressed as {@link com.googlecode.ipv6.IPv6NetworkMask}) of the subnets + * @return iterator of the splitted subnets. + * @throws IllegalArgumentException if the requested size is bigger than the original size + */ + public Iterator split(IPv6NetworkMask size) + { + if (size.asPrefixLength() < this.getNetmask().asPrefixLength()) + throw new IllegalArgumentException(String.format("Can not split a network of size %s in subnets of larger size %s", + this.getNetmask().asPrefixLength(), size.asPrefixLength())); + + return new IPv6NetworkSplitsIterator(size); + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } + + private final class IPv6NetworkSplitsIterator implements Iterator + { + private final IPv6NetworkMask size; + + private IPv6Network current; + + private BigInteger nbrAddressesPerSplit; + + public IPv6NetworkSplitsIterator(IPv6NetworkMask size) + { + this.size = size; + this.nbrAddressesPerSplit = BigInteger.ONE.shiftLeft(128 - size.asPrefixLength()); + this.current = IPv6Network.fromAddressAndMask(IPv6Network.this.address, size); + } + + @Override + public boolean hasNext() + { + return current.getLast().compareTo(IPv6Network.this.getLast()) <= 0; + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + IPv6Network result = current; + current = calculateNext(current); + return result; + } + else + { + throw new NoSuchElementException(); + } + } + + private IPv6Network calculateNext(IPv6Network current) + { + BigInteger next = current.address.toBigInteger().add(nbrAddressesPerSplit); + return IPv6Network.fromAddressAndMask(IPv6Address.fromBigInteger(next), size); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("This iterator provides read only access"); + } + } +} diff --git a/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..66268ed --- /dev/null +++ b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = bitSetOf(first.getLowBits(), first.getHighBits()); + final BitSet lastBits = bitSetOf(last.getLowBits(), last.getHighBits()); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..ee4394b --- /dev/null +++ b/tags/java-ipv6-0.15/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,150 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength < 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval [0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = bitSetOf(addressToValidate.getLowBits(), addressToValidate.getHighBits()); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..834d561 --- /dev/null +++ b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,274 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..bc6d32b --- /dev/null +++ b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,264 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import junit.framework.Assert; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Iterator; +import java.util.List; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static com.googlecode.ipv6.IPv6AddressRange.fromFirstAndLast; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + + @Test + public void compareTo() + { + final IPv6AddressRange a = + fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange b = + fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange c = + fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange d = + fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + + Assert.assertTrue(a.compareTo(b) > 0); + Assert.assertTrue(a.compareTo(c) < 0); + Assert.assertTrue(a.compareTo(d) < 0); + Assert.assertTrue(b.compareTo(c) < 0); + Assert.assertTrue(b.compareTo(d) < 0); + Assert.assertTrue(c.compareTo(d) > 0); + + Assert.assertTrue(a.compareTo(a) == 0); + Assert.assertTrue(b.compareTo(b) == 0); + Assert.assertTrue(c.compareTo(c) == 0); + Assert.assertTrue(d.compareTo(d) == 0); + } + + @Test + public void size() + { + assertEquals(BigInteger.valueOf(11), fromFirstAndLast(fromString("::"), fromString("::a")).size()); + assertEquals(BigInteger.valueOf(131074), fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:5:5")).size()); + assertEquals(BigInteger.valueOf(2).pow(128), + fromFirstAndLast(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")).size()); + } + + @Test + public void subnets_alreadyANetwork() + { + // testrange is already a network + IPv6AddressRange testRange = fromFirstAndLast(fromString("::ffff:10.0.0.0"), fromString("::ffff:10.0.0.255")); + List expected = ImmutableList.of(IPv6Network.fromString("::ffff:10.0.0.0/120")); + assertEquals(expected, Lists.newArrayList(testRange.toSubnets())); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_smallTest1() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("::ffff:0.0.0.3"), fromString("::ffff:0.0.0.17")); + List expected = ImmutableList.of(IPv6Network.fromString("::ffff:0.0.0.3/128"), + IPv6Network.fromString("::ffff:0.0.0.4/126"), + IPv6Network.fromString("::ffff:0.0.0.8/125"), + IPv6Network.fromString("::ffff:0.0.0.17/127")); + assertEquals(expected, Lists.newArrayList(testRange.toSubnets())); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_smallTest2() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("::ffff:192.168.0.3"), fromString("::ffff:192.168.0.17")); + List expected = ImmutableList.of(IPv6Network.fromString("::ffff:192.168.0.3/128"), + IPv6Network.fromString("::ffff:192.168.0.4/126"), + IPv6Network.fromString("::ffff:192.168.0.8/125"), + IPv6Network.fromString("::ffff:192.168.0.17/127")); + assertEquals(expected, Lists.newArrayList(testRange.toSubnets())); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_smallTest3() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("::ffff:192.168.1.250"), fromString("::ffff:192.168.2.2")); + List expected = ImmutableList.of(IPv6Network.fromString("::ffff:192.168.1.250/127"), + IPv6Network.fromString("::ffff:192.168.1.252/126"), + IPv6Network.fromString("::ffff:192.168.2.0/127"), + IPv6Network.fromString("::ffff:192.168.2.2/128")); + assertEquals(expected, Lists.newArrayList(testRange.toSubnets())); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_smallTest4() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("::ffff:192.3.1.250"), fromString("::ffff:192.168.2.2")); + List expected = ImmutableList.of(IPv6Network.fromString("::ffff:192.3.1.250/127"), + IPv6Network.fromString("::ffff:192.3.1.252/126"), + IPv6Network.fromString("::ffff:192.3.2.0/119"), + IPv6Network.fromString("::ffff:192.3.4.0/118"), + IPv6Network.fromString("::ffff:192.3.8.0/117"), + IPv6Network.fromString("::ffff:192.3.16.0/116"), + IPv6Network.fromString("::ffff:192.3.32.0/115"), + IPv6Network.fromString("::ffff:192.3.64.0/114"), + IPv6Network.fromString("::ffff:192.3.128.0/113"), + IPv6Network.fromString("::ffff:192.4.0.0/110"), + IPv6Network.fromString("::ffff:192.8.0.0/109"), + IPv6Network.fromString("::ffff:192.16.0.0/108"), + IPv6Network.fromString("::ffff:192.32.0.0/107"), + IPv6Network.fromString("::ffff:192.64.0.0/106"), + IPv6Network.fromString("::ffff:192.128.0.0/107"), + IPv6Network.fromString("::ffff:192.160.0.0/109"), + IPv6Network.fromString("::ffff:192.168.0.0/119"), + IPv6Network.fromString("::ffff:192.168.2.0/127"), + IPv6Network.fromString("::ffff:192.168.2.2/128")); + assertEquals(expected, Lists.newArrayList(testRange.toSubnets())); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_largeTest1() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("a:b:c:d::"), + fromString("a:b:c:e::")); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_largeTestAlreadyANetwork() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("a:b:c:c::"), fromString("a:b:c:f:ffff:ffff:ffff:ffff")); + IPv6Network network = IPv6Network.fromTwoAddresses(testRange.getFirst(), testRange.getLast()); + assertEquals(testRange, network); // just to prove that the range is already a network + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + /** + * Check that a given list of subnets denotes exactly the same addresses as a given range. + */ + private void checkSubnetsSameAsRange(Iterator subnets, IPv6AddressRange range) + { + IPv6Network current = subnets.next(); + + // first + assertEquals(range.getFirst(), current.getFirst()); + + // networks should be non overlapping and consecutive + while (subnets.hasNext()) + { + IPv6Network prev = current; + current = subnets.next(); + assertEquals(prev.getLast().add(1), current.getFirst()); + } + + // last + assertEquals(range.getLast(), current.getLast()); + } + +} diff --git a/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..66798ac --- /dev/null +++ b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,427 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.math.BigInteger; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesFromRFC5952() + { + assertEquals("::", fromString("::").toString()); + assertEquals("1:2:3:4::", fromString("1:2:3:4::").toString()); + assertEquals("::1:2:3:4", fromString("::1:2:3:4").toString()); + assertEquals("1::2", fromString("1::2").toString()); + assertEquals("::2", fromString("::2").toString()); + assertEquals("1::", fromString("1::").toString()); + assertEquals("a31:200:3abc::de4", fromString("0a31:0200:3AbC::0dE4").toString()); + assertEquals("1::4:0:0:0", fromString("1:0:0:0:4:0:0:0").toString()); + + assertEquals("2001:db8::1", fromString("2001:db8::1").toString()); + assertEquals("2001:db8::2:1", fromString("2001:db8:0:0:0:0:2:1").toString()); + assertEquals("2001:db8:0:1:1:1:1:1", fromString("2001:db8:0:1:1:1:1:1").toString()); + assertEquals("2001:db8::1:0:0:1", fromString("2001:db8::1:0:0:1").toString()); + assertEquals("2001:0:0:1::1", fromString("2001:0:0:1:0:0:0:1").toString()); + + assertEquals("1:0:0:4::", fromString("1:0:0:4::").toString()); + } + + @Test + public void parseSomeRealIPv4MappedAddresses() + { + assertEquals("::ffff:0.0.0.1", fromString("::ffff:0.0.0.1").toString()); + assertEquals("::ffff:192.168.139.50", fromString("::ffff:192.168.139.50").toString()); + assertEquals("::ffff:192.168.139.50", fromString("::ffff:c0a8:8b32").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void constructFromByteArray() throws UnknownHostException + { + assertEquals("1:1:1:1:1:1:1:1", + IPv6Address.fromByteArray( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}) + .toString()); + } + + @Test + public void convertToByteArray() throws UnknownHostException + { + assertArrayEquals( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}, + fromString("1:1:1:1:1:1:1:1").toByteArray()); + } + + @Test + public void convertToAndFromByteArray() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + byte[] randomBytes = new byte[16]; + rg.nextBytes(randomBytes); + + final IPv6Address address = IPv6Address.fromByteArray(randomBytes); + assertArrayEquals(randomBytes, address.toByteArray()); + } + } + + @Test + public void convertToBigInteger() throws UnknownHostException + { + assertEquals(BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE), IPv6Address.MAX.toBigInteger()); + assertEquals(BigInteger.ONE.shiftLeft(128).subtract(BigInteger.valueOf(16)), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0").toBigInteger()); + } + + @Test + public void convertToAndFromBigInteger() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + byte[] randomBytes = new byte[16]; + rg.nextBytes(randomBytes); + BigInteger randomBigInteger = new BigInteger(1, randomBytes); + + final IPv6Address address = IPv6Address.fromBigInteger(randomBigInteger); + assertEquals(randomBigInteger, address.toBigInteger()); + } + } + + @Test + public void positionOfLongestRunOfZeroes() + { + assertArrayEquals(new int[]{0, 8}, fromString("::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{3, 5}, fromString("a:b:c::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{2, 5}, fromString("a:b::c").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{4, 4}, fromString("a:0:0:c::").startAndLengthOfLongestRunOfZeroes()); + } + + @Test + public void toStringCompactsLongestRunOfZeroes() + { + assertEquals("0:0:1::", fromString("0:0:1::").toString()); // and not ::1:0:0:0:0:0 + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void setBit() + { + assertEquals(fromString("::1"), fromString("::").setBit(0)); + assertEquals(fromString("::2"), fromString("::").setBit(1)); + assertEquals(fromString("::3"), fromString("::").setBit(0).setBit(1)); + + assertEquals(fromString("0:0:0:1::"), fromString("::").setBit(64)); + assertEquals(fromString("0:0:0:2::"), fromString("::").setBit(65)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + + @Test + public void isIPv4Mapped() + { + assertFalse(fromString("::").isIPv4Mapped()); + assertFalse(fromString("::0001:ffff:1234:5678").isIPv4Mapped()); + assertFalse(fromString("1::ffff:1234:5678").isIPv4Mapped()); + assertFalse(fromString("::afff:1234:5678").isIPv4Mapped()); + + assertTrue(fromString("::ffff:1234:5678").isIPv4Mapped()); + assertTrue(fromString("::ffff:192.168.123.123").isIPv4Mapped()); + } + + @Test + public void isMulticast() + { + assertFalse(fromString("::").isMulticast()); + + assertTrue(fromString("ff12::ffff:1234:5678").isMulticast()); + } + + @Test + public void isLinkLocal() + { + assertFalse(fromString("::").isLinkLocal()); + + assertTrue(fromString("fe80::ffff:1234:5678").isLinkLocal()); + } + + @Test + public void isSiteLocal() + { + assertFalse(fromString("::").isSiteLocal()); + + assertTrue(fromString("fec0::ffff:1234:5678").isSiteLocal()); + } + +} diff --git a/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..960d630 --- /dev/null +++ b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..0eea592 --- /dev/null +++ b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Negative() + { + new IPv6NetworkMask(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..21d9e61 --- /dev/null +++ b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,190 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Iterator; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + + @Test + public void contains() + { + assertTrue(IPv6Network.fromString("ffff::/8").contains(IPv6Address.fromString("ffff::1"))); + assertTrue(IPv6Network.fromString("1234:5678:1234:5678::/64").contains(IPv6Address.fromString("1234:5678:1234:5678:1::"))); + } + + @Test + public void zeroNetworkContainsEverything() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + + assertTrue(IPv6Network.fromString("::/0").contains(randomAddress)); + assertTrue(IPv6Network.fromString("abcd:effe:dcba::/0").contains(randomAddress)); + } + + @Test + public void iteratorShouldStartWithFirstAndEndWithLast() + { + IPv6Network ipv6Network = IPv6Network.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0000/126"); + Iterator iterator = ipv6Network.iterator(); + int i = 0; + for (; iterator.hasNext(); i++) + { + assertEquals(IPv6Address.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:000" + i), iterator.next()); + } + assertEquals(4, i); + } + + @Test + public void split() + { + { + IPv6Network slash120 = IPv6Network.fromString("::ffff:192.168.123.0/120"); + Iterator splits = slash120.split(IPv6NetworkMask.fromPrefixLength(121)); + verifySplits(splits, 2, IPv6Network.fromString("::ffff:192.168.123.0/121"), + IPv6Network.fromString("::ffff:192.168.123.128/121")); + } + + { + IPv6Network slash30 = IPv6Network.fromString("a:b:c:d:1:2:3:4/30"); // a:8:: is the host address after masking with /30 + Iterator splits = slash30.split(IPv6NetworkMask.fromPrefixLength(40)); + verifySplits(splits, (int) Math.pow(2, 40 - 30), + IPv6Network.fromString("a:8::/40"), + IPv6Network.fromString("a:8:100::/40"), + IPv6Network.fromString("a:8:200::/40")); + } + } + + @Test(expected = IllegalArgumentException.class) + public void splitInLargerSize() + { + IPv6Network ipv6Network = IPv6Network.fromString("1:2:3:4:5:6:7:8/69"); + ipv6Network.split(IPv6NetworkMask.fromPrefixLength(68)); // 68 subnet is bigger than 69 + } + + @Test + public void splitInSameSize() + { + IPv6Network ipv6Network = IPv6Network.fromString("1:2:3:4:5:6:7:8/69"); + Iterator splits = ipv6Network.split(IPv6NetworkMask.fromPrefixLength(69)); + verifySplits(splits, 1, ipv6Network); + } + + /** + * Verify a splitted network. + * + * @param splits splits to verify + * @param expectedNbr number of expected splits + * @param expectedSplits the first splits in the list to expect (check as many as you want but no need to check them all) + */ + private void verifySplits(Iterator splits, int expectedNbr, IPv6Network... expectedSplits) + { + int nChecked = 0; + + // check the ones that are explicitely passed + for (IPv6Network expectedSplit : expectedSplits) + { + assertEquals(expectedSplit, splits.next()); + nChecked++; + } + + // merely check count for the others + while (splits.hasNext()) + { + splits.next(); + nChecked++; + } + + assertEquals(expectedNbr, nChecked); + } + +} diff --git a/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..25f69d9 --- /dev/null +++ b/tags/java-ipv6-0.15/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,152 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +import java.util.Iterator; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address iPv4MappedIPv6Address = IPv6Address.fromString("::ffff:192.168.0.1"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipAddressRangeConvertToSubnets() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("::1:ffcc"), + IPv6Address.fromString("::2:0")); + + Iterator subnetsIterator = range.toSubnets(); + while (subnetsIterator.hasNext()) + System.out.println(subnetsIterator.next()); + + // prints ::1:ffcc/126 ::1:ffd0/124 ::1:ffe0/123 ::2:0/128 (i.e. the minimal set of networks that define the original range) + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test + public void ipNetworkSplitInSmallerSubnets() + { + final IPv6Network network = IPv6Network.fromString("1:2:3:4:5:6:7:0/120"); + + Iterator splits = network.split(IPv6NetworkMask.fromPrefixLength(124)); + while (splits.hasNext()) + System.out.println(splits.next()); + + // prints 1:2:3:4:5:6:7:0/124, 1:2:3:4:5:6:7:10/124, 1:2:3:4:5:6:7:20/124, ... until 1:2:3:4:5:6:7:f0/124 (16 in total) + } + + @Test + public void ipNetworkNotationChoices() + { + IPv6Network prefixLengthNotation = IPv6Network.fromString("::1/16"); + IPv6Network addressNotation = + IPv6Network.fromAddressAndMask(IPv6Address.fromString("::"), IPv6NetworkMask.fromAddress(IPv6Address.fromString("ffff::"))); + System.out.println(prefixLengthNotation.equals(addressNotation)); // prints true + System.out.println(prefixLengthNotation); // prints ::/16 + System.out.println(prefixLengthNotation.getFirst() + "/" + prefixLengthNotation.getNetmask().asAddress()); // prints ::/ffff:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.5/pom.xml b/tags/java-ipv6-0.5/pom.xml new file mode 100644 index 0000000..ae8aac7 --- /dev/null +++ b/tags/java-ipv6-0.5/pom.xml @@ -0,0 +1,115 @@ + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.5 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.5 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.5 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.5 + + + + + junit + junit + 4.10 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.7 + 1.7 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..cdd9d28 --- /dev/null +++ b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,376 @@ +package com.googlecode.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private final long highBits; + + private final long lowBits; + + public IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = IPv6AddressHelpers.expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something postive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * @return String representation of the IPv6 address, using shorthand notation whenever possible. + */ + @Override + public String toString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + boolean shortHandNotationUsed = false; + boolean shortHandNotationBusy = false; + for (int i = 0; i < strings.length; i++) + { + if (!shortHandNotationUsed && i < N_SHORTS - 1 && IPv6AddressHelpers.isZeroString(strings[i]) && IPv6AddressHelpers + .isZeroString(strings[i + 1])) + { + shortHandNotationUsed = true; + shortHandNotationBusy = true; + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(IPv6AddressHelpers.isZeroString(strings[i]) && shortHandNotationBusy)) + { + shortHandNotationBusy = false; + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + public short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..dc68f22 --- /dev/null +++ b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,110 @@ +package com.googlecode.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..38cf6a1 --- /dev/null +++ b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,467 @@ +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool in between the given first and last address (inclusive) which is completely free. The given subnet size is the network + * mask (thus size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of + * this size (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet + * size). + * + * @param first first ip address of the range + * @param last last ip address of the range + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public IPv6AddressPool(final IPv6Address first, final IPv6Address last, final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + this(first, last, allocationSubnetSize, new TreeSet(Arrays.asList(new IPv6AddressRange(first, last))), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param first first ip address of the range + * @param last last ip address of the range + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6Address first, final IPv6Address last, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = new IPv6AddressRange(first, last); + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(first, last, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(first, last, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6Address first, IPv6Address last, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(first, last, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be usefull. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6Address first, IPv6Address last, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(first) >= 0 && toValidate.last().getLast().compareTo(last) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6Address first, IPv6Address last, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (first.numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (last.numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = new IPv6Network(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(getFirst(), getLast(), allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(new IPv6AddressRange(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(new IPv6AddressRange(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(new IPv6AddressRange(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(getFirst(), getLast(), allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..1f5171d --- /dev/null +++ b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,202 @@ +package com.googlecode.ipv6; + +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + public IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(new IPv6AddressRange(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(new IPv6AddressRange(first, last.subtract(1))); + else + return Arrays.asList(new IPv6AddressRange(first, address.subtract(1)), + new IPv6AddressRange(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return new IPv6AddressRange(address, last); + else if (address.compareTo(last) > 0) + return new IPv6AddressRange(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(new IPv6AddressRange(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(new IPv6AddressRange(first, network.getFirst().subtract(1))); + else + return Arrays.asList(new IPv6AddressRange(first, network.getFirst().subtract(1)), + new IPv6AddressRange(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + @Override + public int compareTo(IPv6AddressRange that) + { + if (this.first != that.first) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + return current = current.add(1); + else + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..91eec69 --- /dev/null +++ b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,141 @@ +package com.googlecode.ipv6; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + public IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Construct from address and prefix length. + * + * @param address address + * @param prefixLength prefix length + */ + public IPv6Network(IPv6Address address, int prefixLength) + { + super(address.maskWithNetworkMask(new IPv6NetworkMask(prefixLength)), + address.maximumAddressWithNetworkMask(new IPv6NetworkMask(prefixLength))); + + final IPv6NetworkMask networkMask = new IPv6NetworkMask(prefixLength); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Construct from first and last address. This will construct the smallest possible network ("longest prefix length") which contains + * both addresses. + * + * @param first first address + * @param last last address + */ + public IPv6Network(IPv6Address first, IPv6Address last) + { + super(first.maskWithNetworkMask(new IPv6NetworkMask(IPv6NetworkHelpers.longestPrefixLength(first, last))), + first.maximumAddressWithNetworkMask(new IPv6NetworkMask(IPv6NetworkHelpers.longestPrefixLength(first, last)))); + + this.networkMask = new IPv6NetworkMask(IPv6NetworkHelpers.longestPrefixLength(first, last)); + this.address = this.getFirst(); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return new IPv6Network(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } +} diff --git a/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..8ea0a3c --- /dev/null +++ b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,30 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = BitSet.valueOf(new long[]{first.getLowBits(), first.getHighBits()}); + final BitSet lastBits = BitSet.valueOf(new long[]{last.getLowBits(), last.getHighBits()}); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..bc591c5 --- /dev/null +++ b/tags/java-ipv6-0.5/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,120 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public IPv6NetworkMask(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + this.prefixLength = iPv6Address.numberOfLeadingOnes(); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public IPv6NetworkMask(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + this.prefixLength = prefixLength; + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = BitSet.valueOf(new long[]{addressToValidate.getLowBits(), addressToValidate.getHighBits()}); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..f079038 --- /dev/null +++ b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,227 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6AddressPool; +import com.googlecode.ipv6.IPv6Network; +import com.googlecode.ipv6.IPv6NetworkMask; +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + new IPv6AddressPool(fromString("2001::1"), fromString("2001::ffff:ffff"), new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:fffe"), new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:ffff"), new IPv6NetworkMask(120)); + new IPv6AddressPool(fromString("2001::ab00"), fromString("2001::ffff:ffff"), new IPv6NetworkMask(120)); + new IPv6AddressPool(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), fromString("2001::ffff:ffff"), new IPv6NetworkMask(120)); + new IPv6AddressPool(fromString("2001::0"), fromString("2001::ffff:ffff"), new IPv6NetworkMask(120)); + new IPv6AddressPool(fromString("2001::abcd:ef00"), fromString("2001::abcd:efff"), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(new IPv6Network(fromString("::1"), 128)); + + assertTrue(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::5"), new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(new IPv6Network(fromString("::" + i), 128))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("2001::"), fromString("2001::ffff:ffff"), new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("2001::"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("2001::100"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("2001::200"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::ffff:0"), 120))); + + pool = pool.deAllocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(new IPv6Network(fromString("::1"), 128)); + + assertFalse(pool.isFree(new IPv6Network(fromString("::1"), 128))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate(new IPv6Network(fromString("::1"), 128))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::1"), new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(new IPv6Network(fromString("::99"), 128)); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::1"), fromString("::5"), new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(new IPv6Network(fromString("::" + i), 128)); + assertFalse(pool.isFree(new IPv6Network(fromString("::" + i), 128))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("2001::"), fromString("2001::ffff:ffff"), new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(new IPv6Network(fromString("2001::"), 120)); + assertEquals(new IPv6Network(fromString("2001::"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(new IPv6Network(fromString("2001::200"), 120)); + assertEquals(new IPv6Network(fromString("2001::200"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + pool = pool.allocate(new IPv6Network(fromString("2001::100"), 120)); + assertEquals(new IPv6Network(fromString("2001::100"), 120), pool.getLastAllocated()); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::ffff:0"), 120))); + + pool = pool.deAllocate(new IPv6Network(fromString("2001::100"), 120)); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::"), 120))); + assertTrue(pool.isFree(new IPv6Network(fromString("2001::100"), 120))); + assertFalse(pool.isFree(new IPv6Network(fromString("2001::200"), 120))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::"), i), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), i), + pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = new IPv6AddressPool(fromString("::"), fromString("::ffff:ffff:ffff:ffff"), new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::"), i), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(new IPv6Network(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), i), + pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = new IPv6AddressPool(fromString("::"), fromString("::ffff:ffff:ffff:ffff"), new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..b16fcfb --- /dev/null +++ b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,92 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6Address; +import com.googlecode.ipv6.IPv6AddressRange; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + new IPv6AddressRange(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(new IPv6AddressRange(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(new IPv6AddressRange(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")).size()); + assertEquals(1, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")).size()); + assertEquals(1, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")).size()); + assertEquals(0, new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")).size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : new IPv6AddressRange(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + +} diff --git a/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..a900737 --- /dev/null +++ b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,264 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6Address; +import com.googlecode.ipv6.IPv6NetworkMask; +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + +} diff --git a/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..bf08071 --- /dev/null +++ b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,26 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6NetworkHelpers; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..2d11ac7 --- /dev/null +++ b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,44 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6Address; +import com.googlecode.ipv6.IPv6NetworkMask; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(new IPv6NetworkMask(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Zero() + { + new IPv6NetworkMask(0); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + new IPv6NetworkMask(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..27904f5 --- /dev/null +++ b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,71 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6Address; +import com.googlecode.ipv6.IPv6Network; +import com.googlecode.ipv6.IPv6NetworkMask; +import org.junit.Test; + +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromFirstAndLastAddress() + { + assertEquals(new IPv6Network(fromString("::"), 126), new IPv6Network(fromString("::1"), fromString("::2"))); + assertEquals(new IPv6Network(fromString("a:b::"), 44), new IPv6Network(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", new IPv6Network(fromString("::"), 126).toString()); + assertEquals("a:b:c:d::/64", new IPv6Network(fromString("a:b:c:d::"), 64).toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = new IPv6Network(new IPv6Address(rg.nextLong(), rg.nextLong()), rg.nextInt(128) + 1); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(new IPv6NetworkMask(new IPv6Address(0x8000000000000000L, 0x0L)), IPv6Network.fromString("a:b:c::/1").getNetmask()); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xfffffffffffffffeL, 0x0L)), IPv6Network.fromString("a:b:c::/63").getNetmask()); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0x0L)), IPv6Network.fromString("a:b:c::/64").getNetmask()); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + assertEquals(new IPv6NetworkMask(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + + +} diff --git a/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..e99a42e --- /dev/null +++ b/tags/java-ipv6-0.5/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,93 @@ +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only + * to call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = new IPv6AddressRange(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6Network range = new IPv6Network(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = new IPv6NetworkMask(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = new IPv6NetworkMask(IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = new IPv6NetworkMask(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(new IPv6NetworkMask(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(new IPv6NetworkMask(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = new IPv6AddressPool(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff"), new IPv6NetworkMask(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.6/pom.xml b/tags/java-ipv6-0.6/pom.xml new file mode 100644 index 0000000..1a75547 --- /dev/null +++ b/tags/java-ipv6-0.6/pom.xml @@ -0,0 +1,115 @@ + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.6 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.6 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.6 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.6 + + + + + junit + junit + 4.10 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.7 + 1.7 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..09b6004 --- /dev/null +++ b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,382 @@ +package com.googlecode.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private final long highBits; + + private final long lowBits; + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = IPv6AddressHelpers.expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something postive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * @return String representation of the IPv6 address, using shorthand notation whenever possible. + */ + @Override + public String toString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + boolean shortHandNotationUsed = false; + boolean shortHandNotationBusy = false; + for (int i = 0; i < strings.length; i++) + { + if (!shortHandNotationUsed && i < N_SHORTS - 1 && IPv6AddressHelpers.isZeroString(strings[i]) && IPv6AddressHelpers + .isZeroString(strings[i + 1])) + { + shortHandNotationUsed = true; + shortHandNotationBusy = true; + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(IPv6AddressHelpers.isZeroString(strings[i]) && shortHandNotationBusy)) + { + shortHandNotationBusy = false; + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + public short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..dc68f22 --- /dev/null +++ b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,110 @@ +package com.googlecode.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..4422a69 --- /dev/null +++ b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,467 @@ +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..5d5f690 --- /dev/null +++ b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,207 @@ +package com.googlecode.ipv6; + +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + @Override + public int compareTo(IPv6AddressRange that) + { + if (this.first != that.first) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + return current = current.add(1); + else + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..c4049f7 --- /dev/null +++ b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,133 @@ +package com.googlecode.ipv6; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } +} diff --git a/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..8ea0a3c --- /dev/null +++ b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,30 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = BitSet.valueOf(new long[]{first.getLowBits(), first.getHighBits()}); + final BitSet lastBits = BitSet.valueOf(new long[]{last.getLowBits(), last.getHighBits()}); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..9584311 --- /dev/null +++ b/tags/java-ipv6-0.6/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,132 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = BitSet.valueOf(new long[]{addressToValidate.getLowBits(), addressToValidate.getHighBits()}); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..7c471d3 --- /dev/null +++ b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,258 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..4447859 --- /dev/null +++ b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,94 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + IPv6AddressRange.fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + +} diff --git a/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..a900737 --- /dev/null +++ b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,264 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6Address; +import com.googlecode.ipv6.IPv6NetworkMask; +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + +} diff --git a/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..bf08071 --- /dev/null +++ b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,26 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6NetworkHelpers; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..15b0e81 --- /dev/null +++ b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,42 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Zero() + { + new IPv6NetworkMask(0); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..2222f58 --- /dev/null +++ b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,79 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + +} diff --git a/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..39eab13 --- /dev/null +++ b/tags/java-ipv6-0.6/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,97 @@ +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.7/pom.xml b/tags/java-ipv6-0.7/pom.xml new file mode 100644 index 0000000..5be0740 --- /dev/null +++ b/tags/java-ipv6-0.7/pom.xml @@ -0,0 +1,115 @@ + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.7 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.7 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.7 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.7 + + + + + junit + junit + 4.10 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/BitSetHelpers.java b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/BitSetHelpers.java new file mode 100644 index 0000000..5cd1585 --- /dev/null +++ b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/BitSetHelpers.java @@ -0,0 +1,35 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + * method. However, for java-6 compatibility, we go this way. + * + * @author Jan Van Besien + */ +public class BitSetHelpers +{ + static BitSet bitSetOf(long lowerBits, long upperBits) + { + final BitSet bitSet = new BitSet(); + convert(lowerBits, 0, bitSet); + convert(upperBits, Long.SIZE, bitSet); + return bitSet; + } + + static void convert(long value, int bitSetOffset, BitSet bits) + { + int index = 0; + while (value != 0L) + { + if (value % 2L != 0) + { + bits.set(bitSetOffset + index); + } + ++index; + value = value >>> 1; + } + } + +} diff --git a/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..09b6004 --- /dev/null +++ b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,382 @@ +package com.googlecode.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private final long highBits; + + private final long lowBits; + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = IPv6AddressHelpers.expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something postive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * @return String representation of the IPv6 address, using shorthand notation whenever possible. + */ + @Override + public String toString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + boolean shortHandNotationUsed = false; + boolean shortHandNotationBusy = false; + for (int i = 0; i < strings.length; i++) + { + if (!shortHandNotationUsed && i < N_SHORTS - 1 && IPv6AddressHelpers.isZeroString(strings[i]) && IPv6AddressHelpers + .isZeroString(strings[i + 1])) + { + shortHandNotationUsed = true; + shortHandNotationBusy = true; + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(IPv6AddressHelpers.isZeroString(strings[i]) && shortHandNotationBusy)) + { + shortHandNotationBusy = false; + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + public short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..dc68f22 --- /dev/null +++ b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,110 @@ +package com.googlecode.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..4422a69 --- /dev/null +++ b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,467 @@ +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..5d5f690 --- /dev/null +++ b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,207 @@ +package com.googlecode.ipv6; + +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + @Override + public int compareTo(IPv6AddressRange that) + { + if (this.first != that.first) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + return current = current.add(1); + else + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..c4049f7 --- /dev/null +++ b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,133 @@ +package com.googlecode.ipv6; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } +} diff --git a/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..dfd50dd --- /dev/null +++ b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,32 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = bitSetOf(first.getLowBits(), first.getHighBits()); + final BitSet lastBits = bitSetOf(last.getLowBits(), last.getHighBits()); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..a5ed7e4 --- /dev/null +++ b/tags/java-ipv6-0.7/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,134 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = bitSetOf(addressToValidate.getLowBits(), addressToValidate.getHighBits()); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..7c471d3 --- /dev/null +++ b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,258 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..4447859 --- /dev/null +++ b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,94 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + IPv6AddressRange.fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + +} diff --git a/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..a900737 --- /dev/null +++ b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,264 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6Address; +import com.googlecode.ipv6.IPv6NetworkMask; +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + +} diff --git a/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..bf08071 --- /dev/null +++ b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,26 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6NetworkHelpers; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..15b0e81 --- /dev/null +++ b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,42 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Zero() + { + new IPv6NetworkMask(0); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..2222f58 --- /dev/null +++ b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,79 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + +} diff --git a/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..39eab13 --- /dev/null +++ b/tags/java-ipv6-0.7/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,97 @@ +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.8/pom.xml b/tags/java-ipv6-0.8/pom.xml new file mode 100644 index 0000000..800d6fb --- /dev/null +++ b/tags/java-ipv6-0.8/pom.xml @@ -0,0 +1,115 @@ + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.8 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.8 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.8 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.8 + + + + + junit + junit + 4.10 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/BitSetHelpers.java b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/BitSetHelpers.java new file mode 100644 index 0000000..c353848 --- /dev/null +++ b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/BitSetHelpers.java @@ -0,0 +1,35 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + * method. However, for java-6 compatibility, we go this way. + * + * @author Jan Van Besien + */ +class BitSetHelpers +{ + static BitSet bitSetOf(long lowerBits, long upperBits) + { + final BitSet bitSet = new BitSet(); + convert(lowerBits, 0, bitSet); + convert(upperBits, Long.SIZE, bitSet); + return bitSet; + } + + static void convert(long value, int bitSetOffset, BitSet bits) + { + int index = 0; + while (value != 0L) + { + if (value % 2L != 0) + { + bits.set(bitSetOffset + index); + } + ++index; + value = value >>> 1; + } + } + +} diff --git a/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..09b6004 --- /dev/null +++ b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,382 @@ +package com.googlecode.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private final long highBits; + + private final long lowBits; + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = IPv6AddressHelpers.expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something postive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * @return String representation of the IPv6 address, using shorthand notation whenever possible. + */ + @Override + public String toString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + boolean shortHandNotationUsed = false; + boolean shortHandNotationBusy = false; + for (int i = 0; i < strings.length; i++) + { + if (!shortHandNotationUsed && i < N_SHORTS - 1 && IPv6AddressHelpers.isZeroString(strings[i]) && IPv6AddressHelpers + .isZeroString(strings[i + 1])) + { + shortHandNotationUsed = true; + shortHandNotationBusy = true; + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(IPv6AddressHelpers.isZeroString(strings[i]) && shortHandNotationBusy)) + { + shortHandNotationBusy = false; + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + public short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..dc68f22 --- /dev/null +++ b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,110 @@ +package com.googlecode.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..4422a69 --- /dev/null +++ b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,467 @@ +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..ae1f05c --- /dev/null +++ b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,216 @@ +package com.googlecode.ipv6; + +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + /** + * The natural order of {@link com.googlecode.ipv6.IPv6AddressRange}s orders them on increasing first addresses, and on increasing last + * address if the first address would be equal. + *

+ * Note that the natural order does thus not compare sizes of ranges. + * + * @param that range to compare with + * @return negative, zero or positive depending on whether this is smaller, equal or greater than that + */ + @Override + public int compareTo(IPv6AddressRange that) + { + if (!this.first.equals(that.first)) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + return current = current.add(1); + else + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..c4049f7 --- /dev/null +++ b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,133 @@ +package com.googlecode.ipv6; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } +} diff --git a/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..dfd50dd --- /dev/null +++ b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,32 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = bitSetOf(first.getLowBits(), first.getHighBits()); + final BitSet lastBits = bitSetOf(last.getLowBits(), last.getHighBits()); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..a5ed7e4 --- /dev/null +++ b/tags/java-ipv6-0.8/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,134 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength <= 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval ]0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = bitSetOf(addressToValidate.getLowBits(), addressToValidate.getHighBits()); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..7c471d3 --- /dev/null +++ b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,258 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..e42d1ab --- /dev/null +++ b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,119 @@ +package com.googlecode.ipv6; + +import junit.framework.Assert; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + IPv6AddressRange.fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + + @Test + public void compareTo() + { + final IPv6AddressRange a = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange b = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange c = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange d = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + + Assert.assertTrue(a.compareTo(b) > 0); + Assert.assertTrue(a.compareTo(c) < 0); + Assert.assertTrue(a.compareTo(d) < 0); + Assert.assertTrue(b.compareTo(c) < 0); + Assert.assertTrue(b.compareTo(d) < 0); + Assert.assertTrue(c.compareTo(d) > 0); + + Assert.assertTrue(a.compareTo(a) == 0); + Assert.assertTrue(b.compareTo(b) == 0); + Assert.assertTrue(c.compareTo(c) == 0); + Assert.assertTrue(d.compareTo(d) == 0); + } +} diff --git a/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..a900737 --- /dev/null +++ b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,264 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6Address; +import com.googlecode.ipv6.IPv6NetworkMask; +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + +} diff --git a/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..bf08071 --- /dev/null +++ b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,26 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6NetworkHelpers; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..15b0e81 --- /dev/null +++ b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,42 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Zero() + { + new IPv6NetworkMask(0); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..2222f58 --- /dev/null +++ b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,79 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + +} diff --git a/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..39eab13 --- /dev/null +++ b/tags/java-ipv6-0.8/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,97 @@ +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/tags/java-ipv6-0.9/pom.xml b/tags/java-ipv6-0.9/pom.xml new file mode 100644 index 0000000..95d7dc8 --- /dev/null +++ b/tags/java-ipv6-0.9/pom.xml @@ -0,0 +1,115 @@ + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.9 + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.9 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.9 + scm:svn:https://java-ipv6.googlecode.com/svn/tags/java-ipv6-0.9 + + + + + junit + junit + 4.10 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/BitSetHelpers.java b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/BitSetHelpers.java new file mode 100644 index 0000000..c353848 --- /dev/null +++ b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/BitSetHelpers.java @@ -0,0 +1,35 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + * method. However, for java-6 compatibility, we go this way. + * + * @author Jan Van Besien + */ +class BitSetHelpers +{ + static BitSet bitSetOf(long lowerBits, long upperBits) + { + final BitSet bitSet = new BitSet(); + convert(lowerBits, 0, bitSet); + convert(upperBits, Long.SIZE, bitSet); + return bitSet; + } + + static void convert(long value, int bitSetOffset, BitSet bits) + { + int index = 0; + while (value != 0L) + { + if (value % 2L != 0) + { + bits.set(bitSetOffset + index); + } + ++index; + value = value >>> 1; + } + } + +} diff --git a/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6Address.java b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..5e3d93f --- /dev/null +++ b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,386 @@ +package com.googlecode.ipv6; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private final long highBits; + + private final long lowBits; + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String longNotation = IPv6AddressHelpers.expandShortNotation(string); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something postive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() == 0) + { + return new IPv6Address(0, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * @return String representation of the IPv6 address, using shorthand notation whenever possible. + */ + @Override + public String toString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + boolean shortHandNotationUsed = false; + boolean shortHandNotationBusy = false; + for (int i = 0; i < strings.length; i++) + { + if (!shortHandNotationUsed && i < N_SHORTS - 1 && IPv6AddressHelpers.isZeroString(strings[i]) && IPv6AddressHelpers + .isZeroString(strings[i + 1])) + { + shortHandNotationUsed = true; + shortHandNotationBusy = true; + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(IPv6AddressHelpers.isZeroString(strings[i]) && shortHandNotationBusy)) + { + shortHandNotationBusy = false; + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + public short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..dc68f22 --- /dev/null +++ b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,110 @@ +package com.googlecode.ipv6; + +import java.util.Arrays; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isZeroString(String string) + { + return "0".equals(string); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } +} diff --git a/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..4422a69 --- /dev/null +++ b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,467 @@ +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..ae1f05c --- /dev/null +++ b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,216 @@ +package com.googlecode.ipv6; + +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new Ipv6AddressRangeIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + /** + * The natural order of {@link com.googlecode.ipv6.IPv6AddressRange}s orders them on increasing first addresses, and on increasing last + * address if the first address would be equal. + *

+ * Note that the natural order does thus not compare sizes of ranges. + * + * @param that range to compare with + * @return negative, zero or positive depending on whether this is smaller, equal or greater than that + */ + @Override + public int compareTo(IPv6AddressRange that) + { + if (!this.first.equals(that.first)) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class Ipv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + return current = current.add(1); + else + throw new NoSuchElementException(); + } + + @Override + public void remove() + { + IPv6AddressRange.this.remove(current); + } + } +} diff --git a/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6Network.java b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..c4049f7 --- /dev/null +++ b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,133 @@ +package com.googlecode.ipv6; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } +} diff --git a/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..dfd50dd --- /dev/null +++ b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,32 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = bitSetOf(first.getLowBits(), first.getHighBits()); + final BitSet lastBits = bitSetOf(last.getLowBits(), last.getHighBits()); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..4b45914 --- /dev/null +++ b/tags/java-ipv6-0.9/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,134 @@ +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength < 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval [0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = bitSetOf(addressToValidate.getLowBits(), addressToValidate.getHighBits()); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..7c471d3 --- /dev/null +++ b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,258 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..e42d1ab --- /dev/null +++ b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,119 @@ +package com.googlecode.ipv6; + +import junit.framework.Assert; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + IPv6AddressRange.fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(IPv6AddressRange.fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : IPv6AddressRange.fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + + @Test + public void compareTo() + { + final IPv6AddressRange a = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange b = + IPv6AddressRange.fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange c = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange d = + IPv6AddressRange.fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + + Assert.assertTrue(a.compareTo(b) > 0); + Assert.assertTrue(a.compareTo(c) < 0); + Assert.assertTrue(a.compareTo(d) < 0); + Assert.assertTrue(b.compareTo(c) < 0); + Assert.assertTrue(b.compareTo(d) < 0); + Assert.assertTrue(c.compareTo(d) > 0); + + Assert.assertTrue(a.compareTo(a) == 0); + Assert.assertTrue(b.compareTo(b) == 0); + Assert.assertTrue(c.compareTo(c) == 0); + Assert.assertTrue(d.compareTo(d) == 0); + } +} diff --git a/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..a900737 --- /dev/null +++ b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,264 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6Address; +import com.googlecode.ipv6.IPv6NetworkMask; +import org.junit.Test; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + +} diff --git a/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..bf08071 --- /dev/null +++ b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,26 @@ +package com.googlecode.ipv6; + +import com.googlecode.ipv6.IPv6NetworkHelpers; +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..f598d34 --- /dev/null +++ b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,42 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Negative() + { + new IPv6NetworkMask(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..e51a6b8 --- /dev/null +++ b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,96 @@ +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + + @Test + public void contains() + { + assertTrue(IPv6Network.fromString("ffff::/8").contains(IPv6Address.fromString("ffff::1"))); + assertTrue(IPv6Network.fromString("1234:5678:1234:5678::/64").contains(IPv6Address.fromString("1234:5678:1234:5678:1::"))); + } + + @Test + public void zeroNetworkContainsEverything() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + + assertTrue(IPv6Network.fromString("::/0").contains(randomAddress)); + assertTrue(IPv6Network.fromString("abcd:effe:dcba::/0").contains(randomAddress)); + } +} diff --git a/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/examples/Examples.java b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..39eab13 --- /dev/null +++ b/tags/java-ipv6-0.9/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,97 @@ +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/trunk/LICENSE b/trunk/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/trunk/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/trunk/NOTICE b/trunk/NOTICE new file mode 100644 index 0000000..a4605c4 --- /dev/null +++ b/trunk/NOTICE @@ -0,0 +1,2 @@ + Java IPv6 + Copyright 2013 Jan Van Besien \ No newline at end of file diff --git a/trunk/pom.xml b/trunk/pom.xml new file mode 100644 index 0000000..8ebbc97 --- /dev/null +++ b/trunk/pom.xml @@ -0,0 +1,149 @@ + + + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + com.googlecode.java-ipv6 + java-ipv6 + 0.16-SNAPSHOT + jar + Java IPv6 Library + http://code.google.com/p/java-ipv6 + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://java-ipv6.googlecode.com/svn/trunk + scm:svn:https://java-ipv6.googlecode.com/svn/trunk/ + scm:svn:https://java-ipv6.googlecode.com/svn/trunk/ + + + + + junit + junit + 4.10 + test + + + com.google.guava + guava + 14.0.1 + test + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.1 + + https://java-ipv6.googlecode.com/svn/tags/ + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + + ${basedir} + false + + LICENSE + NOTICE + + + + + + + + sonatype-oss-release + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.0-beta-4 + + + validate + + create + + + + + true + true + + + + + + + diff --git a/trunk/src/main/java/com/googlecode/ipv6/BitSetHelpers.java b/trunk/src/main/java/com/googlecode/ipv6/BitSetHelpers.java new file mode 100644 index 0000000..698c51e --- /dev/null +++ b/trunk/src/main/java/com/googlecode/ipv6/BitSetHelpers.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +/** + * This class contains some helpers for working with BitSets. These are generally not necessary in JDK7, since the BitSet.valueOf(long[]) + * method. However, for java-6 compatibility, we go this way. + * + * @author Jan Van Besien + */ +class BitSetHelpers +{ + static BitSet bitSetOf(long lowerBits, long upperBits) + { + final BitSet bitSet = new BitSet(); + convert(lowerBits, 0, bitSet); + convert(upperBits, Long.SIZE, bitSet); + return bitSet; + } + + static void convert(long value, int bitSetOffset, BitSet bits) + { + int index = 0; + while (value != 0L) + { + if (value % 2L != 0) + { + bits.set(bitSetOffset + index); + } + ++index; + value = value >>> 1; + } + } + +} diff --git a/trunk/src/main/java/com/googlecode/ipv6/IPv6Address.java b/trunk/src/main/java/com/googlecode/ipv6/IPv6Address.java new file mode 100644 index 0000000..48e5e21 --- /dev/null +++ b/trunk/src/main/java/com/googlecode/ipv6/IPv6Address.java @@ -0,0 +1,602 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.math.BigInteger; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.LongBuffer; +import java.util.Arrays; + +import static com.googlecode.ipv6.IPv6AddressHelpers.prefixWithZeroBytes; + +/** + * Immutable representation of an IPv6 address. + * + * @author Jan Van Besien + */ +public final class IPv6Address implements Comparable +{ + private static final int N_SHORTS = 8; + + private static final int N_BYTES = 16; + + public static final IPv6Address MAX = IPv6Address.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); + + private final long highBits; + + private final long lowBits; + + IPv6Address(long highBits, long lowBits) + { + this.highBits = highBits; + this.lowBits = lowBits; + } + + /** + * Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + * IPv6Addresses from a {@link String} or an {@link java.net.InetAddress}. The internal representation of an IPv6Address is exactly + * these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address. + * + * @param highBits highest order bits + * @param lowBits lowest order bits + */ + public static IPv6Address fromLongs(long highBits, long lowBits) + { + return new IPv6Address(highBits, lowBits); + } + + /** + * Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + * "::". IPv4-Mapped IPv6 addresses such as "::ffff:123.456.123.456" are also supported. + * + * @param string string representation + * @return IPv6 address + */ + public static IPv6Address fromString(final String string) + { + if (string == null) + throw new IllegalArgumentException("can not parse [null]"); + + final String withoutIPv4MappedNotation = IPv6AddressHelpers.rewriteIPv4MappedNotation(string); + final String longNotation = IPv6AddressHelpers.expandShortNotation(withoutIPv4MappedNotation); + + final long[] longs = tryParseStringArrayIntoLongArray(string, longNotation); + + IPv6AddressHelpers.validateLongs(longs); + + return IPv6AddressHelpers.mergeLongArrayIntoIPv6Address(longs); + } + + private static long[] tryParseStringArrayIntoLongArray(String string, String longNotation) + { + try + { + return IPv6AddressHelpers.parseStringArrayIntoLongArray(longNotation.split(":")); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("can not parse [" + string + "]"); + } + } + + /** + * Create an IPv6 address from a java.net.Inet6Address. + * + * @param inetAddress Inet6Address representation + * @return IPv6 address + */ + public static IPv6Address fromInetAddress(final InetAddress inetAddress) + { + if (inetAddress == null) + throw new IllegalArgumentException("can not construct from [null]"); + + return fromString(inetAddress.getHostAddress()); + } + + public InetAddress toInetAddress() throws UnknownHostException + { + return Inet6Address.getByName(toString()); + } + + /** + * Create an IPv6 address from a byte array. + * + * @param bytes byte array with 16 bytes (interpreted unsigned) + * @return IPv6 address + */ + public static IPv6Address fromByteArray(final byte[] bytes) + { + if (bytes == null) + throw new IllegalArgumentException("can not construct from [null]"); + if (bytes.length != N_BYTES) + throw new IllegalArgumentException("the byte array to construct from should be 16 bytes long"); + + ByteBuffer buf = ByteBuffer.allocate(N_BYTES); + for (byte b : bytes) + { + buf.put(b); + } + + buf.rewind(); + LongBuffer longBuffer = buf.asLongBuffer(); + return new IPv6Address(longBuffer.get(), longBuffer.get()); + } + + /** + * @return byte[] representation + */ + public byte[] toByteArray() + { + ByteBuffer byteBuffer = ByteBuffer.allocate(N_BYTES).putLong(highBits).putLong(lowBits); + return byteBuffer.array(); + } + + /** + * Create an IPv6 address from a (positive) {@link java.math.BigInteger}. The magnitude of the {@link java.math.BigInteger} represents + * the IPv6 address value. Or in other words, the {@link java.math.BigInteger} with value N defines the Nth possible IPv6 address. + * + * @param bigInteger {@link java.math.BigInteger} value + * @return IPv6 address + */ + public static IPv6Address fromBigInteger(final BigInteger bigInteger) + { + if (bigInteger == null) + throw new IllegalArgumentException("can not construct from [null]"); + if (bigInteger.compareTo(BigInteger.ZERO) < 0) + throw new IllegalArgumentException("can not construct from negative value"); + if (bigInteger.compareTo(MAX.toBigInteger()) > 0) + throw new IllegalArgumentException("bigInteger represents a value bigger than 2^128 - 1"); + + byte[] bytes = bigInteger.toByteArray(); + + if (bytes[0] == 0) + { + // a zero byte was added to represent the (always positive, hence zero) sign bit + return fromByteArray(prefixWithZeroBytes(Arrays.copyOfRange(bytes, 1, bytes.length), N_BYTES)); + } + else + { + return fromByteArray(prefixWithZeroBytes(bytes, N_BYTES)); + } + } + + /** + * @return {@link java.math.BigInteger} representation. The magnitude of the {@link java.math.BigInteger} represents the IPv6 address + * value. Or in other words, the {@link java.math.BigInteger} with value N defines the Nth possible IPv6 address. + */ + public BigInteger toBigInteger() + { + return new BigInteger(1, toByteArray()); + } + + /** + * Addition. Will never overflow, but wraps around when the highest ip address has been reached. + * + * @param value value to add + * @return new IPv6 address + */ + public IPv6Address add(int value) + { + final long newLowBits = lowBits + value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we added something positive and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we added something negative and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached. + * + * @param value value to substract + * @return new IPv6 address + */ + public IPv6Address subtract(int value) + { + final long newLowBits = lowBits - value; + + if (value >= 0) + { + if (IPv6AddressHelpers.isLessThanUnsigned(lowBits, newLowBits)) + { + // oops, we subtracted something postive and the result is bigger -> overflow detected (carry over one bit from high to low) + return new IPv6Address(highBits - 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + else + { + if (IPv6AddressHelpers.isLessThanUnsigned(newLowBits, lowBits)) + { + // oops, we subtracted something negative and the result is smaller -> overflow detected (carry over one bit from low to high) + return new IPv6Address(highBits + 1, newLowBits); + } + else + { + // no overflow + return new IPv6Address(highBits, newLowBits); + } + } + } + + /** + * Mask the address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are zero + */ + public IPv6Address maskWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0); + } + else if (networkMask.asPrefixLength() == 0) + { + return new IPv6Address(0, 0); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits & (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + // apply mask on high bits, low bits completely 0 + return new IPv6Address(this.highBits & (0xFFFFFFFFFFFFFFFFL << (64 - networkMask.asPrefixLength())), 0); + } + } + + /** + * Calculate the maximum address with the given network mask. + * + * @param networkMask network mask + * @return an address of which the last 128 - networkMask.asPrefixLength() bits are one + */ + public IPv6Address maximumAddressWithNetworkMask(final IPv6NetworkMask networkMask) + { + if (networkMask.asPrefixLength() == 128) + { + return this; + } + else if (networkMask.asPrefixLength() == 64) + { + return new IPv6Address(this.highBits, 0xFFFFFFFFFFFFFFFFL); + } + else if (networkMask.asPrefixLength() > 64) + { + // apply mask on low bits only + final int remainingPrefixLength = networkMask.asPrefixLength() - 64; + return new IPv6Address(this.highBits, this.lowBits | (0xFFFFFFFFFFFFFFFFL >>> remainingPrefixLength)); + } + else + { + // apply mask on high bits, low bits completely 1 + return new IPv6Address(this.highBits | (0xFFFFFFFFFFFFFFFFL >>> networkMask.asPrefixLength()), 0xFFFFFFFFFFFFFFFFL); + } + } + + /** + * Set a bit in the address. + * + * @param bit to set (in the range [0, 127]) + * @return an address with the given bit set + */ + public IPv6Address setBit(final int bit) + { + if (bit < 0 || bit > 127) + throw new IllegalArgumentException("can only set bits in the interval [0, 127]"); + + if (bit < 64) + { + return new IPv6Address(this.highBits, this.lowBits | (1 << bit)); + } + else + { + return new IPv6Address(this.highBits | (1 << (bit - 64)), this.lowBits); + } + } + + /** + * Returns true if the address is an IPv4-mapped IPv6 address. In these addresses, the first 80 bits are zero, the next 16 bits are one, + * and the remaining 32 bits are the IPv4 address. + * + * @return true if the address is an IPv4-mapped IPv6 addresses. + */ + public boolean isIPv4Mapped() + { + return this.highBits == 0 // 64 zero bits + && (this.lowBits & 0xFFFF000000000000L) == 0 // 16 more zero bits + && (this.lowBits & 0x0000FFFF00000000L) == 0x0000FFFF00000000L; // 16 one bits and the remainder is the IPv4 address + } + + /** + * @return true if the address is an IPv6 multicast address (an address in the network ff00::/8) + */ + public boolean isMulticast() + { + return IPv6Network.MULTICAST_NETWORK.contains(this); + } + + /** + * @return true if the address is an IPv6 site-local address (an address in the network fec0::/48) + */ + public boolean isSiteLocal() + { + return IPv6Network.SITE_LOCAL_NETWORK.contains(this); + } + + /** + * @return true if the address is an IPv6 link-local address (an address in the network fe80::/64) + */ + public boolean isLinkLocal() + { + return IPv6Network.LINK_LOCAL_NETWORK.contains(this); + } + + /** + * Returns a string representation of the IPv6 address. It will use shorthand notation and special notation for IPv4-mapped IPv6 + * addresses whenever possible. + * + * @return String representation of the IPv6 address + */ + @Override + public String toString() + { + if (isIPv4Mapped()) + return toIPv4MappedAddressString(); + else + return toShortHandNotationString(); + } + + private String toIPv4MappedAddressString() + { + int byteZero = (int) ((this.lowBits & 0x00000000FF000000L) >> 24); + int byteOne = (int) ((this.lowBits & 0x0000000000FF0000L) >> 16); + int byteTwo = (int) ((this.lowBits & 0x000000000000FF00L) >> 8); + int byteThree = (int) ((this.lowBits & 0x00000000000000FFL)); + + final StringBuilder result = new StringBuilder("::ffff:"); + result.append(byteZero).append(".").append(byteOne).append(".").append(byteTwo).append(".").append(byteThree); + + return result.toString(); + } + + private String toShortHandNotationString() + { + final String[] strings = toArrayOfShortStrings(); + + final StringBuilder result = new StringBuilder(); + + int[] shortHandNotationPositionAndLength = startAndLengthOfLongestRunOfZeroes(); + int shortHandNotationPosition = shortHandNotationPositionAndLength[0]; + int shortHandNotationLength = shortHandNotationPositionAndLength[1]; + + boolean useShortHandNotation = shortHandNotationLength > 1; // RFC5952 recommends not to use shorthand notation for a single zero + + for (int i = 0; i < strings.length; i++) + { + if (useShortHandNotation && i == shortHandNotationPosition) + { + if (i == 0) + result.append("::"); + else + result.append(":"); + } + else if (!(i > shortHandNotationPosition && i < shortHandNotationPosition + shortHandNotationLength)) + { + result.append(strings[i]); + if (i < N_SHORTS - 1) + result.append(":"); + } + } + + return result.toString().toLowerCase(); + } + + private String[] toArrayOfShortStrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%x", shorts[i]); + } + return strings; + } + + /** + * @return String representation of the IPv6 address, never using shorthand notation. + */ + public String toLongString() + { + final String[] strings = toArrayOfZeroPaddedstrings(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < strings.length - 1; i++) + { + result.append(strings[i]).append(":"); + } + + result.append(strings[strings.length - 1]); + + return result.toString(); + } + + private String[] toArrayOfZeroPaddedstrings() + { + final short[] shorts = toShortArray(); + final String[] strings = new String[shorts.length]; + for (int i = 0; i < shorts.length; i++) + { + strings[i] = String.format("%04x", shorts[i]); + } + return strings; + } + + private short[] toShortArray() + { + final short[] shorts = new short[N_SHORTS]; + + for (int i = 0; i < N_SHORTS; i++) + { + if (IPv6AddressHelpers.inHighRange(i)) + shorts[i] = (short) (((highBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + else + shorts[i] = (short) (((lowBits << i * 16) >>> 16 * (N_SHORTS - 1)) & 0xFFFF); + } + + return shorts; + } + + int[] startAndLengthOfLongestRunOfZeroes() + { + int longestConsecutiveZeroes = 0; + int longestConsecutiveZeroesPos = -1; + short[] shorts = toShortArray(); + for (int pos = 0; pos < shorts.length; pos++) + { + int consecutiveZeroesAtCurrentPos = countConsecutiveZeroes(shorts, pos); + if (consecutiveZeroesAtCurrentPos > longestConsecutiveZeroes) + { + longestConsecutiveZeroes = consecutiveZeroesAtCurrentPos; + longestConsecutiveZeroesPos = pos; + } + } + + return new int[]{longestConsecutiveZeroesPos, longestConsecutiveZeroes}; + } + + private int countConsecutiveZeroes(short[] shorts, int offset) + { + int count = 0; + for (int i = offset; i < shorts.length && shorts[i] == 0; i++) + { + count++; + } + + return count; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6Address that = (IPv6Address) o; + + if (highBits != that.highBits) return false; + if (lowBits != that.lowBits) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = (int) (lowBits ^ (lowBits >>> 32)); + result = 31 * result + (int) (highBits ^ (highBits >>> 32)); + return result; + } + + public int compareTo(IPv6Address that) + { + if (this.highBits == that.highBits) + if (this.lowBits == that.lowBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.lowBits, that.lowBits) ? -1 : 1; + else if (this.highBits == that.highBits) + return 0; + else + return IPv6AddressHelpers.isLessThanUnsigned(this.highBits, that.highBits) ? -1 : 1; + } + + public long getHighBits() + { + return highBits; + } + + public long getLowBits() + { + return lowBits; + } + + public int numberOfTrailingZeroes() + { + return lowBits == 0 ? + Long.numberOfTrailingZeros(highBits) + 64 : + Long.numberOfTrailingZeros(lowBits); + } + + public int numberOfTrailingOnes() + { + // count trailing ones in "value" by counting the trailing zeroes in "value + 1" + final IPv6Address plusOne = this.add(1); + return plusOne.getLowBits() == 0 ? + Long.numberOfTrailingZeros(plusOne.getHighBits()) + 64 : + Long.numberOfTrailingZeros(plusOne.getLowBits()); + } + + public int numberOfLeadingZeroes() + { + return highBits == 0 ? + Long.numberOfLeadingZeros(lowBits) + 64 : + Long.numberOfLeadingZeros(highBits); + } + + public int numberOfLeadingOnes() + { + // count leading ones in "value" by counting leading zeroes in "~ value" + final IPv6Address flipped = new IPv6Address(~this.highBits, ~this.lowBits); + return flipped.numberOfLeadingZeroes(); + } + +} diff --git a/trunk/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java b/trunk/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java new file mode 100644 index 0000000..8403cfe --- /dev/null +++ b/trunk/src/main/java/com/googlecode/ipv6/IPv6AddressHelpers.java @@ -0,0 +1,175 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.Arrays; +import java.util.regex.Pattern; + +/** + * Helper methods used by IPv6Address. + * + * @author Jan Van Besien + */ +public final class IPv6AddressHelpers +{ + static long[] parseStringArrayIntoLongArray(String[] strings) + { + final long[] longs = new long[strings.length]; + for (int i = 0; i < strings.length; i++) + { + longs[i] = Long.parseLong(strings[i], 16); + } + return longs; + } + + static void validateLongs(long[] longs) + { + if (longs.length != 8) + throw new IllegalArgumentException("an IPv6 address should contain 8 shorts [" + Arrays.toString(longs) + "]"); + + for (long l : longs) + { + if (l < 0) throw new IllegalArgumentException("each element should be positive [" + Arrays.toString(longs) + "]"); + if (l > 0xFFFF) throw new IllegalArgumentException("each element should be less than 0xFFFF [" + Arrays.toString(longs) + "]"); + } + } + + static IPv6Address mergeLongArrayIntoIPv6Address(long[] longs) + { + long high = 0L; + long low = 0L; + + for (int i = 0; i < longs.length; i++) + { + if (inHighRange(i)) + high |= (longs[i] << ((longs.length - i - 1) * 16)); + else + low |= (longs[i] << ((longs.length - i - 1) * 16)); + } + + return new IPv6Address(high, low); + } + + static boolean inHighRange(int shortNumber) + { + return shortNumber >= 0 && shortNumber < 4; + } + + static String expandShortNotation(String string) + { + if (!string.contains("::")) + { + return string; + } + else if (string.equals("::")) + { + return generateZeroes(8); + } + else + { + final int numberOfColons = countOccurrences(string, ':'); + if (string.startsWith("::")) + return string.replace("::", generateZeroes((7 + 2) - numberOfColons)); + else if (string.endsWith("::")) + return string.replace("::", ":" + generateZeroes((7 + 2) - numberOfColons)); + else + return string.replace("::", ":" + generateZeroes((7 + 2 - 1) - numberOfColons)); + } + } + + private static final Pattern DOT_DELIM = Pattern.compile("\\."); + + /** + * Replaces a w.x.y.z substring at the end of the given string with corresponding hexadecimal notation. This is useful in case the + * string was using IPv4-Mapped address notation. + */ + static String rewriteIPv4MappedNotation(String string) + { + if (!string.contains(".")) + { + return string; + } + else + { + int lastColon = string.lastIndexOf(":"); + String firstPart = string.substring(0, lastColon + 1); + String mappedIPv4Part = string.substring(lastColon + 1); + + if (mappedIPv4Part.contains(".")) + { + String[] dotSplits = DOT_DELIM.split(mappedIPv4Part); + if (dotSplits.length != 4) + throw new IllegalArgumentException(String.format("can not parse [%s]", string)); + + StringBuilder rewrittenString = new StringBuilder(); + rewrittenString.append(firstPart); + int byteZero = Integer.parseInt(dotSplits[0]); + int byteOne = Integer.parseInt(dotSplits[1]); + int byteTwo = Integer.parseInt(dotSplits[2]); + int byteThree = Integer.parseInt(dotSplits[3]); + + rewrittenString.append(String.format("%02x", byteZero)); + rewrittenString.append(String.format("%02x", byteOne)); + rewrittenString.append(":"); + rewrittenString.append(String.format("%02x", byteTwo)); + rewrittenString.append(String.format("%02x", byteThree)); + + return rewrittenString.toString(); + } + else + { + throw new IllegalArgumentException(String.format("can not parse [%s]", string)); + } + } + } + + public static int countOccurrences(String haystack, char needle) + { + int count = 0; + for (int i = 0; i < haystack.length(); i++) + { + if (haystack.charAt(i) == needle) + { + count++; + } + } + return count; + } + + public static String generateZeroes(int number) + { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number; i++) + { + builder.append("0:"); + } + + return builder.toString(); + } + + static boolean isLessThanUnsigned(long a, long b) + { + return (a < b) ^ ((a < 0) != (b < 0)); + } + + static byte[] prefixWithZeroBytes(byte[] original, int newSize) + { + byte[] target = new byte[newSize]; + System.arraycopy(original, 0, target, newSize - original.length, original.length); + return target; + } +} diff --git a/trunk/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java b/trunk/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java new file mode 100644 index 0000000..77b9a0f --- /dev/null +++ b/trunk/src/main/java/com/googlecode/ipv6/IPv6AddressPool.java @@ -0,0 +1,483 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + + +import java.util.*; + +/** + * Immutable representation of an IPv6 address pool. + *

+ * An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + * Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + * range. + * + * @author Jan Van Besien + */ +public final class IPv6AddressPool +{ + private final IPv6AddressRange underlyingRange; + + private final SortedSet freeRanges; + + private final IPv6NetworkMask allocationSubnetSize; + + private final IPv6Network lastAllocated; + + /** + * Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + * size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + * (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size). + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + */ + public static IPv6AddressPool fromRangeAndSubnet(final IPv6AddressRange range, + final IPv6NetworkMask allocationSubnetSize) + { + // in the beginning, all is free + return new IPv6AddressPool(range, allocationSubnetSize, new TreeSet(Arrays.asList(range)), null); + } + + /** + * Private constructor to construct a pool with a given set of free ranges and a network which was just allocated. + * + * @param range range from within to allocate + * @param allocationSubnetSize size of the subnets that will be allocated + * @param freeRanges free ranges in the allocatable IP address range + */ + private IPv6AddressPool(final IPv6AddressRange range, final IPv6NetworkMask allocationSubnetSize, + final SortedSet freeRanges, final IPv6Network lastAllocated) + { + this.underlyingRange = range; + + this.allocationSubnetSize = allocationSubnetSize; + this.freeRanges = Collections.unmodifiableSortedSet(freeRanges); + this.lastAllocated = lastAllocated; + + validateFreeRanges(underlyingRange, freeRanges); + validateRangeIsMultipleOfSubnetsOfGivenSize(underlyingRange, allocationSubnetSize); + } + + private void validateFreeRanges(IPv6AddressRange range, SortedSet toValidate) + { + if (!toValidate.isEmpty() && !checkWithinBounds(range, toValidate)) + throw new IllegalArgumentException("invalid free ranges: not all within bounds of overall range"); + + // TODO: some more validations would be useful. For example the free ranges should be defragmented and non overlapping etc + } + + private boolean checkWithinBounds(IPv6AddressRange range, SortedSet toValidate) + { + return (toValidate.first().getFirst().compareTo(range.getFirst()) >= 0 + && toValidate.last().getLast().compareTo(range.getLast()) <= 0); + } + + private void validateRangeIsMultipleOfSubnetsOfGivenSize(IPv6AddressRange range, IPv6NetworkMask allocationSubnetSize) + { + final int allocatableBits = 128 - allocationSubnetSize.asPrefixLength(); + + if (range.getFirst().numberOfTrailingZeroes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + "], " + + "first address should end with " + + allocatableBits + " zero bits"); + + if (range.getLast().numberOfTrailingOnes() < allocatableBits) + throw new IllegalArgumentException( + "range [" + this + "] is not aligned with prefix length [" + allocationSubnetSize.asPrefixLength() + + "], last address should end with " + + allocatableBits + " one bits"); + } + + /** + * @return the last IPv6Network which was allocated or null if none was allocated yet + */ + public IPv6Network getLastAllocated() + { + return lastAllocated; + } + + /** + * Allocate the first available subnet from the pool. + * + * @return resulting pool + */ + public IPv6AddressPool allocate() + { + if (!isExhausted()) + { + // get the first range of free subnets, and take the first subnet of that range + final IPv6AddressRange firstFreeRange = freeRanges.first(); + final IPv6Network allocated = IPv6Network.fromAddressAndMask(firstFreeRange.getFirst(), allocationSubnetSize); + + return doAllocate(allocated, firstFreeRange); + } + else + { + // exhausted + return null; + } + } + + /** + * Allocate the given subnet from the pool. + * + * @param toAllocate subnet to allocate from the pool + * @return resulting pool + */ + public IPv6AddressPool allocate(IPv6Network toAllocate) + { + if (!contains(toAllocate)) + throw new IllegalArgumentException( + "can not allocate network which is not contained in the pool to allocate from [" + toAllocate + "]"); + + if (!this.allocationSubnetSize.equals(toAllocate.getNetmask())) + throw new IllegalArgumentException("can not allocate network with prefix length /" + toAllocate.getNetmask().asPrefixLength() + + " from a pool configured to hand out subnets with prefix length /" + + allocationSubnetSize); + + // go find the range that contains the requested subnet + final IPv6AddressRange rangeToAllocateFrom = findFreeRangeContaining(toAllocate); + + if (rangeToAllocateFrom != null) + { + // found a range in which this subnet is free, allocate it + return doAllocate(toAllocate, rangeToAllocateFrom); + } + else + { + // requested subnet not free + return null; + } + } + + private IPv6AddressRange findFreeRangeContaining(IPv6Network toAllocate) + { + // split around the subnet to allocate + final SortedSet head = freeRanges.headSet(toAllocate); + final SortedSet tail = freeRanges.tailSet(toAllocate); + + // the range containing the network to allocate is either the first of the tail, or the last of the head, or it doesn't exist + if (!head.isEmpty() && head.last().contains(toAllocate)) + { + return head.last(); + } + else if (!tail.isEmpty() && tail.first().contains(toAllocate)) + { + return tail.first(); + } + else + { + return null; + } + } + + /** + * Private helper method to perform the allocation of a subnet within one of the free ranges. + * + * @param toAllocate subnet to allocate + * @param rangeToAllocateFrom free range to allocate from + * @return resulting pool + */ + private IPv6AddressPool doAllocate(final IPv6Network toAllocate, final IPv6AddressRange rangeToAllocateFrom) + { + assert freeRanges.contains(rangeToAllocateFrom); + assert rangeToAllocateFrom.contains(toAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + // remove range from free ranges + newFreeRanges.remove(rangeToAllocateFrom); + + // from the range, remove the allocated subnet + final List newRanges = rangeToAllocateFrom.remove(toAllocate); + + // and add the resulting ranges as new free ranges + newFreeRanges.addAll(newRanges); + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, toAllocate); + } + + /** + * Give a network back to the pool (de-allocate). + * + * @param toDeAllocate network to de-allocate + */ + public IPv6AddressPool deAllocate(final IPv6Network toDeAllocate) + { + if (!contains(toDeAllocate)) + { + throw new IllegalArgumentException( + "Network to de-allocate[" + toDeAllocate + "] is not contained in this allocatable range [" + this + "]"); + } + + // find ranges just in front or after the network to deallocate. These are the ranges to merge with to prevent fragmentation. + final IPv6AddressRange freeRangeBeforeNetwork = findFreeRangeBefore(toDeAllocate); + final IPv6AddressRange freeRangeAfterNetwork = findFreeRangeAfter(toDeAllocate); + + final TreeSet newFreeRanges = new TreeSet(this.freeRanges); + + if ((freeRangeBeforeNetwork == null) && (freeRangeAfterNetwork == null)) + { + // nothing to "defragment" + newFreeRanges.add(toDeAllocate); + } + else + { + if ((freeRangeBeforeNetwork != null) && (freeRangeAfterNetwork != null)) + { + // merge two existing ranges + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), freeRangeAfterNetwork.getLast())); + } + else if (freeRangeBeforeNetwork != null) + { + // append + newFreeRanges.remove(freeRangeBeforeNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(freeRangeBeforeNetwork.getFirst(), toDeAllocate.getLast())); + } + else /*if (freeRangeAfterNetwork != null)*/ + { + // prepend + newFreeRanges.remove(freeRangeAfterNetwork); + newFreeRanges.add(IPv6AddressRange.fromFirstAndLast(toDeAllocate.getFirst(), freeRangeAfterNetwork.getLast())); + } + } + + return new IPv6AddressPool(underlyingRange, allocationSubnetSize, newFreeRanges, getLastAllocated()); + } + + /** + * Private helper method to find the free range just before the given network. + */ + private IPv6AddressRange findFreeRangeBefore(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getLast().add(1).equals(network.getFirst())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * Private helper method to find the free range just after the given address. + */ + private IPv6AddressRange findFreeRangeAfter(IPv6Network network) + { + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.getFirst().subtract(1).equals(network.getLast())) + { + return freeRange; + } + } + + // not found + return null; + } + + /** + * @return true if no subnets are free in this pool, false otherwize + */ + public boolean isExhausted() + { + return freeRanges.isEmpty(); + } + + public boolean isFree(final IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("network invalid [null]"); + + if (!this.allocationSubnetSize.equals(network.getNetmask())) + throw new IllegalArgumentException( + "network of prefix length [" + network.getNetmask().asPrefixLength() + + "] can not be free in a pool which uses prefix length [" + + allocationSubnetSize + "]"); + + // find a free range that contains the network + for (IPv6AddressRange freeRange : freeRanges) + { + if (freeRange.contains(network)) + { + return true; + } + } + + // nothing found + return false; + } + + /** + * @return all networks (all with the same fixed prefix length) which are free in this pool + */ + public Iterable freeNetworks() + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return new Iterator() + { + /* + * Iteration is implemented by allocating from a separate pool. + */ + + private IPv6AddressPool poolInstanceUsedForIteration = IPv6AddressPool.this; + + @Override + public boolean hasNext() + { + return !poolInstanceUsedForIteration.isExhausted(); + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + poolInstanceUsedForIteration = poolInstanceUsedForIteration.allocate(); + return poolInstanceUsedForIteration.lastAllocated; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove not supported"); + } + }; + } + }; + } + +// /** +// * @return all networks (all with the same fixed prefix length) which are allocated in this pool +// */ +// public Iterable allocatedNetworks() +// { +// return new Iterable() +// { +// @Override +// public Iterator iterator() +// { +// return new Iterator() +// { +// @Override +// public boolean hasNext() +// { +// throw new UnsupportedOperationException("TODO: implement hasNext"); +// } +// +// @Override +// public IPv6Network next() +// { +// throw new UnsupportedOperationException("TODO: implement next"); +// } +// +// @Override +// public void remove() +// { +// throw new UnsupportedOperationException("TODO: implement remove"); +// } +// }; +// } +// }; +// } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6AddressPool that = (IPv6AddressPool) o; + + if (allocationSubnetSize != null ? !allocationSubnetSize.equals(that.allocationSubnetSize) : that.allocationSubnetSize != null) + return false; + if (freeRanges != null ? !freeRanges.equals(that.freeRanges) : that.freeRanges != null) return false; + if (lastAllocated != null ? !lastAllocated.equals(that.lastAllocated) : that.lastAllocated != null) return false; + if (underlyingRange != null ? !underlyingRange.equals(that.underlyingRange) : that.underlyingRange != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = underlyingRange != null ? underlyingRange.hashCode() : 0; + result = 31 * result + (freeRanges != null ? freeRanges.hashCode() : 0); + result = 31 * result + (allocationSubnetSize != null ? allocationSubnetSize.hashCode() : 0); + result = 31 * result + (lastAllocated != null ? lastAllocated.hashCode() : 0); + return result; + } + + + // delegation methods + + public boolean contains(IPv6Address address) + { + return underlyingRange.contains(address); + } + + public boolean contains(IPv6AddressRange range) + { + return underlyingRange.contains(range); + } + + public boolean overlaps(IPv6AddressRange range) + { + return underlyingRange.overlaps(range); + } + + public IPv6Address getFirst() + { + return underlyingRange.getFirst(); + } + + public IPv6Address getLast() + { + return underlyingRange.getLast(); + } + + @Override + public String toString() + { + return underlyingRange.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return underlyingRange.toLongString(); + } + +} diff --git a/trunk/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java b/trunk/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java new file mode 100644 index 0000000..522a3e0 --- /dev/null +++ b/trunk/src/main/java/com/googlecode/ipv6/IPv6AddressRange.java @@ -0,0 +1,316 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.math.BigInteger; +import java.util.*; + +/** + * Immutable representation of a continuous range of IPv6 addresses (bounds included). + * + * @author Jan Van Besien + */ +public class IPv6AddressRange implements Comparable, Iterable +{ + private final IPv6Address first; + + private final IPv6Address last; + + IPv6AddressRange(IPv6Address first, IPv6Address last) + { + if (first.compareTo(last) > 0) + throw new IllegalArgumentException("Cannot create ip address range with last address < first address"); + + this.first = first; + this.last = last; + } + + public static IPv6AddressRange fromFirstAndLast(IPv6Address first, IPv6Address last) + { + return new IPv6AddressRange(first, last); + } + + public boolean contains(IPv6Address address) + { + return first.compareTo(address) <= 0 && last.compareTo(address) >= 0; + } + + public boolean contains(IPv6AddressRange range) + { + return contains(range.first) && contains(range.last); + } + + public boolean overlaps(IPv6AddressRange range) + { + return contains(range.first) || contains(range.last) || range.contains(first) || range.contains(last); + } + + /** + * @return an iterator which iterates all addresses in this range, in order. + */ + @Override + public Iterator iterator() + { + return new IPv6AddressRangeIterator(); + } + + /** + * @return number of addresses in the range + */ + public BigInteger size() + { + BigInteger firstAsBigInteger = new BigInteger(1, first.toByteArray()); + BigInteger lastAsBigInteger = new BigInteger(1, last.toByteArray()); + + // note that first and last are included in the range. + return lastAsBigInteger.subtract(firstAsBigInteger).add(BigInteger.ONE); + } + + /** + * Deaggregate a range of IPv6 addresses (which is not necessarily aligned with a single IPv6 network) into a minimal set of non + * overlapping consecutive subnets. + * + * @return iterator of IPv6 networks that all together define the minimal set of subnets by which the range can be represented. + */ + public Iterator toSubnets() + { + return new IPv6AddressRangeAsSubnetsIterator(); + } + + /** + * Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + * effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + * single address). If an address somewhere else in the range is removed, two new ranges are returned. + * + * @param address adddress to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Address address) + { + if (address == null) + throw new IllegalArgumentException("invalid address [null]"); + + if (!contains(address)) + return Collections.singletonList(this); + else if (address.equals(first) && address.equals(last)) + return Collections.emptyList(); + else if (address.equals(first)) + return Collections.singletonList(fromFirstAndLast(first.add(1), last)); + else if (address.equals(last)) + return Collections.singletonList(fromFirstAndLast(first, last.subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, address.subtract(1)), + fromFirstAndLast(address.add(1), last)); + } + + /** + * Extend the range just enough at its head or tail such that the given address is included. + * + * @param address address to extend the range to + * @return new (bigger) range + */ + public IPv6AddressRange extend(IPv6Address address) + { + if (address.compareTo(first) < 0) + return fromFirstAndLast(address, last); + else if (address.compareTo(last) > 0) + return fromFirstAndLast(first, address); + else + return this; + } + + /** + * Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + * removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + * is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + * range is removed, two new ranges are returned. + * + * @param network network to remove from the range + * @return list of resulting ranges + */ + public List remove(IPv6Network network) + { + if (network == null) + throw new IllegalArgumentException("invalid network [null]"); + + if (!contains(network)) + return Collections.singletonList(this); + else if (this.equals(network)) + return Collections.emptyList(); + else if (first.equals(network.getFirst())) + return Collections.singletonList(fromFirstAndLast(network.getLast().add(1), last)); + else if (last.equals(network.getLast())) + return Collections.singletonList(fromFirstAndLast(first, network.getFirst().subtract(1))); + else + return Arrays.asList(fromFirstAndLast(first, network.getFirst().subtract(1)), + fromFirstAndLast(network.getLast().add(1), last)); + + } + + @Override + public String toString() + { + return first.toString() + " - " + last.toString(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return first.toLongString() + " - " + last.toLongString(); + } + + /** + * The natural order of {@link com.googlecode.ipv6.IPv6AddressRange}s orders them on increasing first addresses, and on increasing last + * address if the first address would be equal. + *

+ * Note that the natural order does thus not compare sizes of ranges. + * + * @param that range to compare with + * @return negative, zero or positive depending on whether this is smaller, equal or greater than that + */ + @Override + public int compareTo(IPv6AddressRange that) + { + if (!this.first.equals(that.first)) + return this.first.compareTo(that.first); + else + return this.last.compareTo(that.last); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof IPv6AddressRange)) return false; + + IPv6AddressRange that = (IPv6AddressRange) o; + + if (first != null ? !first.equals(that.first) : that.first != null) return false; + if (last != null ? !last.equals(that.last) : that.last != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (last != null ? last.hashCode() : 0); + return result; + } + + public IPv6Address getFirst() + { + return first; + } + + public IPv6Address getLast() + { + return last; + } + + /** + * @see IPv6AddressRange#iterator() + */ + private final class IPv6AddressRangeIterator implements Iterator + { + private IPv6Address current = first; + + @Override + public boolean hasNext() + { + return current.compareTo(last) <= 0; + } + + @Override + public IPv6Address next() + { + if (hasNext()) + { + IPv6Address result = current; + current = current.add(1); + return result; + } + else + { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("This iterator provides read only access"); + } + } + + private class IPv6AddressRangeAsSubnetsIterator implements Iterator + { + + private IPv6Address base = first; + private IPv6Network next; + + @Override + public IPv6Network next() + { + int step; + + if (hasNext()) + { + step = 0; + + // try setting the step-th bit until we reach a bit that is already set + while (!(base.setBit(step)).equals(base)) + { + // if the max address in this subnet is beyond the end of the range, we went too far + if ((base.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(127 - step)).compareTo(last) > 0)) + { + break; + } + step++; + } + + // the next subnet is found + next = IPv6Network.fromAddressAndMask(base, IPv6NetworkMask.fromPrefixLength(128 - step)); + + // start the next loop after the end of the subnet just found + base = next.getLast().add(1); + } + else + { + throw new NoSuchElementException(); + } + + return next; + } + + @Override + public boolean hasNext() + { + // there is a next subnet as long as we didn't reach the end of the range + return (base.compareTo(last) <= 0); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("This iterator provides read only access"); + } + } +} diff --git a/trunk/src/main/java/com/googlecode/ipv6/IPv6Network.java b/trunk/src/main/java/com/googlecode/ipv6/IPv6Network.java new file mode 100644 index 0000000..f40c5d0 --- /dev/null +++ b/trunk/src/main/java/com/googlecode/ipv6/IPv6Network.java @@ -0,0 +1,225 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.math.BigInteger; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + * not all ranges are valid networks). + * + * @author Jan Van Besien + */ +public final class IPv6Network extends IPv6AddressRange +{ + public static final IPv6Network MULTICAST_NETWORK = fromString("ff00::/8"); + + public static final IPv6Network SITE_LOCAL_NETWORK = fromString("fec0::/48"); + + public static final IPv6Network LINK_LOCAL_NETWORK = fromString("fe80::/64"); + + + private final IPv6Address address; + + private final IPv6NetworkMask networkMask; + + /** + * Construct from address and network mask. + * + * @param address address + * @param networkMask network mask + */ + private IPv6Network(IPv6Address address, IPv6NetworkMask networkMask) + { + super(address.maskWithNetworkMask(networkMask), address.maximumAddressWithNetworkMask(networkMask)); + + this.address = address.maskWithNetworkMask(networkMask); + this.networkMask = networkMask; + } + + /** + * Create an IPv6 network from an IPv6Address and an IPv6NetworkMask + * + * @param address IPv6 address (the network address or any other address within the network) + * @param networkMask IPv6 network mask + * @return IPv6 network + */ + public static IPv6Network fromAddressAndMask(IPv6Address address, IPv6NetworkMask networkMask) + { + return new IPv6Network(address, networkMask); + } + + /** + * Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + * length") which contains both addresses. + * + * @param one address one + * @param two address two, should be bigger than address one + */ + public static IPv6Network fromTwoAddresses(IPv6Address one, IPv6Address two) + { + final IPv6NetworkMask longestPrefixLength = IPv6NetworkMask.fromPrefixLength(IPv6NetworkHelpers.longestPrefixLength(one, two)); + return new IPv6Network(one.maskWithNetworkMask(longestPrefixLength), longestPrefixLength); + } + + /** + * Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128". + * + * @param string string representation + * @return IPv6 network + */ + public static IPv6Network fromString(String string) + { + if (string.indexOf('/') == -1) + { + throw new IllegalArgumentException("Expected format is network-address/prefix-length"); + } + + final String networkAddressString = parseNetworkAddress(string); + int prefixLength = parsePrefixLength(string); + + final IPv6Address networkAddress = IPv6Address.fromString(networkAddressString); + + return fromAddressAndMask(networkAddress, new IPv6NetworkMask(prefixLength)); + } + + private static String parseNetworkAddress(String string) + { + return string.substring(0, string.indexOf('/')); + } + + private static int parsePrefixLength(String string) + { + try + { + return Integer.parseInt(string.substring(string.indexOf('/') + 1)); + } catch (NumberFormatException e) + { + throw new IllegalArgumentException("Prefix length should be a positive integer"); + } + } + + /** + * Split a network in smaller subnets of a given size. + * + * @param size size (expressed as {@link com.googlecode.ipv6.IPv6NetworkMask}) of the subnets + * @return iterator of the splitted subnets. + * @throws IllegalArgumentException if the requested size is bigger than the original size + */ + public Iterator split(IPv6NetworkMask size) + { + if (size.asPrefixLength() < this.getNetmask().asPrefixLength()) + throw new IllegalArgumentException(String.format("Can not split a network of size %s in subnets of larger size %s", + this.getNetmask().asPrefixLength(), size.asPrefixLength())); + + return new IPv6NetworkSplitsIterator(size); + } + + @Override + public String toString() + { + return address.toString() + "/" + networkMask.asPrefixLength(); + } + + /** + * @return like toString but without using shorthand notations for addresses + */ + public String toLongString() + { + return address.toLongString() + "/" + networkMask.asPrefixLength(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + IPv6Network that = (IPv6Network) o; + + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (networkMask != null ? !networkMask.equals(that.networkMask) : that.networkMask != null) return false; + + return true; + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (networkMask != null ? networkMask.hashCode() : 0); + return result; + } + + public IPv6NetworkMask getNetmask() + { + return networkMask; + } + + private final class IPv6NetworkSplitsIterator implements Iterator + { + private final IPv6NetworkMask size; + + private IPv6Network current; + + private BigInteger nbrAddressesPerSplit; + + public IPv6NetworkSplitsIterator(IPv6NetworkMask size) + { + this.size = size; + this.nbrAddressesPerSplit = BigInteger.ONE.shiftLeft(128 - size.asPrefixLength()); + this.current = IPv6Network.fromAddressAndMask(IPv6Network.this.address, size); + } + + @Override + public boolean hasNext() + { + return current.getLast().compareTo(IPv6Network.this.getLast()) <= 0; + } + + @Override + public IPv6Network next() + { + if (hasNext()) + { + IPv6Network result = current; + current = calculateNext(current); + return result; + } + else + { + throw new NoSuchElementException(); + } + } + + private IPv6Network calculateNext(IPv6Network current) + { + BigInteger next = current.address.toBigInteger().add(nbrAddressesPerSplit); + return IPv6Network.fromAddressAndMask(IPv6Address.fromBigInteger(next), size); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("This iterator provides read only access"); + } + } +} diff --git a/trunk/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java b/trunk/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java new file mode 100644 index 0000000..66268ed --- /dev/null +++ b/trunk/src/main/java/com/googlecode/ipv6/IPv6NetworkHelpers.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Helper methods used by IPv6Network. + * + * @author Jan Van Besien + */ +public class IPv6NetworkHelpers +{ + static int longestPrefixLength(IPv6Address first, IPv6Address last) + { + final BitSet firstBits = bitSetOf(first.getLowBits(), first.getHighBits()); + final BitSet lastBits = bitSetOf(last.getLowBits(), last.getHighBits()); + + return countLeadingSimilarBits(firstBits, lastBits); + } + + private static int countLeadingSimilarBits(BitSet a, BitSet b) + { + int result = 0; + for (int i = 127; i >= 0 && (a.get(i) == b.get(i)); i--) + { + result++; + } + + return result; + } +} diff --git a/trunk/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java b/trunk/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java new file mode 100644 index 0000000..ee4394b --- /dev/null +++ b/trunk/src/main/java/com/googlecode/ipv6/IPv6NetworkMask.java @@ -0,0 +1,150 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import java.util.BitSet; + +import static com.googlecode.ipv6.BitSetHelpers.bitSetOf; + +/** + * Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + * starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits. + * + * @author Jan Van Besien + */ +public final class IPv6NetworkMask +{ + private final int prefixLength; + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + IPv6NetworkMask(int prefixLength) + { + if (prefixLength < 0 || prefixLength > 128) + throw new IllegalArgumentException("prefix length should be in interval [0, 128]"); + + this.prefixLength = prefixLength; + } + + + /** + * Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask. + * + * @param iPv6Address address to use as network mask + * @throws IllegalArgumentException if the address is not a valid network mask + */ + public static IPv6NetworkMask fromAddress(final IPv6Address iPv6Address) + { + validateNetworkMask(iPv6Address); + return new IPv6NetworkMask(iPv6Address.numberOfLeadingOnes()); + } + + /** + * Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128]. + * + * @param prefixLength prefix length + * @throws IllegalArgumentException if the prefix length is not in the interval ]0, 128] + */ + public static IPv6NetworkMask fromPrefixLength(int prefixLength) + { + return new IPv6NetworkMask(prefixLength); + } + + private static void validateNetworkMask(IPv6Address addressToValidate) + { + final BitSet addressAsBitSet = bitSetOf(addressToValidate.getLowBits(), addressToValidate.getHighBits()); + if (!addressAsBitSet.get(127)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + else + { + boolean firstZeroFound = false; + for (int i = 127; i >= 0 && !firstZeroFound; i--) + { + if (!addressAsBitSet.get(i)) + { + firstZeroFound = true; + + // a zero -> all the others should also be zero + for (int j = i - 1; j >= 0; j--) + { + if (addressAsBitSet.get(j)) + { + throw new IllegalArgumentException(addressToValidate + " is not a valid network mask"); + } + } + } + } + } + } + + public int asPrefixLength() + { + return prefixLength; + } + + public IPv6Address asAddress() + { + if (prefixLength == 128) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL); + } + else if (prefixLength == 64) + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, 0L); + } + else if (prefixLength > 64) + { + final int remainingPrefixLength = prefixLength - 64; + return new IPv6Address(0xFFFFFFFFFFFFFFFFL, (0xFFFFFFFFFFFFFFFFL << (64 - remainingPrefixLength))); + } + else + { + return new IPv6Address(0xFFFFFFFFFFFFFFFFL << (64 - prefixLength), 0); + } + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IPv6NetworkMask that = (IPv6NetworkMask) o; + + if (prefixLength != that.prefixLength) return false; + + return true; + } + + @Override + public int hashCode() + { + return prefixLength; + } + + @Override + public String toString() + { + return "" + prefixLength; + } +} diff --git a/trunk/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java b/trunk/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java new file mode 100644 index 0000000..834d561 --- /dev/null +++ b/trunk/src/test/java/com/googlecode/ipv6/IPv6AddressPoolTest.java @@ -0,0 +1,274 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressPoolTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedStart() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::1"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructUnalignedEnd() + { + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:fffe")), + new IPv6NetworkMask(120)); + } + + @Test + public void constructAligned() + { + // all these are correctly aligned with the given prefix length, so none should throw exception + + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::ab00"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2000:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("2001::ffff:ffff")), new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::0"), fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::abcd:ef00"), + fromString("2001::abcd:efff")), new IPv6NetworkMask(120)); + } + + @Test + public void autoAllocateAndDeallocateSingle128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", pool.allocate()); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertFalse(pool.isExhausted()); + } + + @Test + public void autoAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void autoAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void manuallyAllocateSingle128Available() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128))); + + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + assertTrue(pool.isExhausted()); + + assertNull("allocation in exhausted range returns null", + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::1"), IPv6NetworkMask.fromPrefixLength(128)))); + } + + @Test(expected = IllegalArgumentException.class) + public void manuallyAllocateSingle128OutOfRange() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::1")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + pool.allocate(IPv6Network.fromAddressAndMask(fromString("::99"), IPv6NetworkMask.fromPrefixLength(128))); + } + + @Test + public void manuallyAllocateMultiple128() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::1"), + fromString("::5")), + new IPv6NetworkMask(128)); + assertFalse(pool.isExhausted()); + + for (int i = 1; i <= 5; i++) + { + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("::" + i), IPv6NetworkMask.fromPrefixLength(128)))); + } + + assertTrue(pool.isExhausted()); + } + + @Test + public void manuallyAllocateAFew120s() + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("2001::"), + fromString("2001::ffff:ffff")), + new IPv6NetworkMask(120)); + assertFalse(pool.isExhausted()); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)), pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.allocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)), + pool.getLastAllocated()); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + + assertFalse(pool.isExhausted()); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::ffff:0"), IPv6NetworkMask.fromPrefixLength(120)))); + + pool = pool.deAllocate(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::"), IPv6NetworkMask.fromPrefixLength(120)))); + assertTrue(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::100"), IPv6NetworkMask.fromPrefixLength(120)))); + assertFalse(pool.isFree(IPv6Network.fromAddressAndMask(fromString("2001::200"), IPv6NetworkMask.fromPrefixLength(120)))); + } + + @Test + public void allocateOnBoundariesLowBits() + { + for (int i = 64; i > 0; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void allocateOnBoundariesHighBits() + { + for (int i = 128; i > 64; i--) + { + IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(i)); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + pool = pool.allocate(); + assertEquals(IPv6Network.fromAddressAndMask(fromString("::").maximumAddressWithNetworkMask(new IPv6NetworkMask(i)).add(1), + IPv6NetworkMask.fromPrefixLength(i)), pool.getLastAllocated()); + } + } + + @Test + public void iterateFreeNetworks() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet(IPv6AddressRange.fromFirstAndLast(fromString("::"), + fromString( + "::ffff:ffff:ffff:ffff")), + new IPv6NetworkMask(66)); + final Set freeNetworks = new HashSet(); + for (IPv6Network network : pool.freeNetworks()) + { + freeNetworks.add(network); + } + + assertEquals(4, freeNetworks.size()); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::4000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::8000:0:0:0/66"))); + assertTrue(freeNetworks.contains(IPv6Network.fromString("::c000:0:0:0/66"))); + } + +} diff --git a/trunk/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java b/trunk/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java new file mode 100644 index 0000000..bc6d32b --- /dev/null +++ b/trunk/src/test/java/com/googlecode/ipv6/IPv6AddressRangeTest.java @@ -0,0 +1,264 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import junit.framework.Assert; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Iterator; +import java.util.List; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static com.googlecode.ipv6.IPv6AddressRange.fromFirstAndLast; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressRangeTest +{ + @Test(expected = IllegalArgumentException.class) + public void constructInvalid() + { + fromFirstAndLast(fromString("::2"), fromString("::1")); + } + + @Test + public void contains() + { + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:9:8:7"))); + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::5:6:7:8"))); + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:2:3:4"))); + + assertTrue(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:12:11:10:9:8"))); + assertTrue(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:2:3:4:5:6:7:8"))); + assertTrue(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("9:10:11:12:13:14:15:16"))); + } + + @Test + public void doesNotContain() + { + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::9:9:9:9"))); + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).contains(fromString("::1:1:1:1"))); + + assertFalse(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("10:10:10:10:10:10:10:10:"))); + assertFalse(fromFirstAndLast(fromString("1:2:3:4:5:6:7:8"), fromString("9:10:11:12:13:14:15:16")) + .contains(fromString("1:1:1:1:1:1:1:1"))); + } + + @Test + public void containsRange() + { + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")))); + assertTrue(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::4:4:4:4"), fromString("::5:5:5:5")))); + } + + @Test + public void doesNotContainRange() + { + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::1:2:3:3"), fromString("::5:6:7:8")))); + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:9")))); + + assertFalse(fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")) + .contains(fromFirstAndLast(fromString("::9:9:9:9"), fromString("::9:9:9:10")))); + } + + @Test + public void remove() + { + assertEquals(2, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::5:5:5:5")) + .size()); + assertEquals(1, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::1:2:3:4")) + .size()); + assertEquals(1, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::5:6:7:8")).remove(fromString("::8:8:8:8")) + .size()); + assertEquals(0, fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:4")).remove(fromString("::1:2:3:4")) + .size()); + } + + @Test + public void iterate() + { + int amountOfAddresses = 0; + for (IPv6Address address : fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:3:8"))) + { + amountOfAddresses++; + } + + assertEquals(5, amountOfAddresses); + } + + @Test + public void compareTo() + { + final IPv6AddressRange a = + fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange b = + fromFirstAndLast(fromString("aaaa:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange c = + fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("cccc:ffff:ffff:ffff:5:5:5:5")); + final IPv6AddressRange d = + fromFirstAndLast(fromString("bbbb:ffff:ffff:ffff:1:1:1:1"), fromString("bbbb:ffff:ffff:ffff:5:5:5:5")); + + Assert.assertTrue(a.compareTo(b) > 0); + Assert.assertTrue(a.compareTo(c) < 0); + Assert.assertTrue(a.compareTo(d) < 0); + Assert.assertTrue(b.compareTo(c) < 0); + Assert.assertTrue(b.compareTo(d) < 0); + Assert.assertTrue(c.compareTo(d) > 0); + + Assert.assertTrue(a.compareTo(a) == 0); + Assert.assertTrue(b.compareTo(b) == 0); + Assert.assertTrue(c.compareTo(c) == 0); + Assert.assertTrue(d.compareTo(d) == 0); + } + + @Test + public void size() + { + assertEquals(BigInteger.valueOf(11), fromFirstAndLast(fromString("::"), fromString("::a")).size()); + assertEquals(BigInteger.valueOf(131074), fromFirstAndLast(fromString("::1:2:3:4"), fromString("::1:2:5:5")).size()); + assertEquals(BigInteger.valueOf(2).pow(128), + fromFirstAndLast(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")).size()); + } + + @Test + public void subnets_alreadyANetwork() + { + // testrange is already a network + IPv6AddressRange testRange = fromFirstAndLast(fromString("::ffff:10.0.0.0"), fromString("::ffff:10.0.0.255")); + List expected = ImmutableList.of(IPv6Network.fromString("::ffff:10.0.0.0/120")); + assertEquals(expected, Lists.newArrayList(testRange.toSubnets())); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_smallTest1() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("::ffff:0.0.0.3"), fromString("::ffff:0.0.0.17")); + List expected = ImmutableList.of(IPv6Network.fromString("::ffff:0.0.0.3/128"), + IPv6Network.fromString("::ffff:0.0.0.4/126"), + IPv6Network.fromString("::ffff:0.0.0.8/125"), + IPv6Network.fromString("::ffff:0.0.0.17/127")); + assertEquals(expected, Lists.newArrayList(testRange.toSubnets())); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_smallTest2() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("::ffff:192.168.0.3"), fromString("::ffff:192.168.0.17")); + List expected = ImmutableList.of(IPv6Network.fromString("::ffff:192.168.0.3/128"), + IPv6Network.fromString("::ffff:192.168.0.4/126"), + IPv6Network.fromString("::ffff:192.168.0.8/125"), + IPv6Network.fromString("::ffff:192.168.0.17/127")); + assertEquals(expected, Lists.newArrayList(testRange.toSubnets())); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_smallTest3() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("::ffff:192.168.1.250"), fromString("::ffff:192.168.2.2")); + List expected = ImmutableList.of(IPv6Network.fromString("::ffff:192.168.1.250/127"), + IPv6Network.fromString("::ffff:192.168.1.252/126"), + IPv6Network.fromString("::ffff:192.168.2.0/127"), + IPv6Network.fromString("::ffff:192.168.2.2/128")); + assertEquals(expected, Lists.newArrayList(testRange.toSubnets())); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_smallTest4() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("::ffff:192.3.1.250"), fromString("::ffff:192.168.2.2")); + List expected = ImmutableList.of(IPv6Network.fromString("::ffff:192.3.1.250/127"), + IPv6Network.fromString("::ffff:192.3.1.252/126"), + IPv6Network.fromString("::ffff:192.3.2.0/119"), + IPv6Network.fromString("::ffff:192.3.4.0/118"), + IPv6Network.fromString("::ffff:192.3.8.0/117"), + IPv6Network.fromString("::ffff:192.3.16.0/116"), + IPv6Network.fromString("::ffff:192.3.32.0/115"), + IPv6Network.fromString("::ffff:192.3.64.0/114"), + IPv6Network.fromString("::ffff:192.3.128.0/113"), + IPv6Network.fromString("::ffff:192.4.0.0/110"), + IPv6Network.fromString("::ffff:192.8.0.0/109"), + IPv6Network.fromString("::ffff:192.16.0.0/108"), + IPv6Network.fromString("::ffff:192.32.0.0/107"), + IPv6Network.fromString("::ffff:192.64.0.0/106"), + IPv6Network.fromString("::ffff:192.128.0.0/107"), + IPv6Network.fromString("::ffff:192.160.0.0/109"), + IPv6Network.fromString("::ffff:192.168.0.0/119"), + IPv6Network.fromString("::ffff:192.168.2.0/127"), + IPv6Network.fromString("::ffff:192.168.2.2/128")); + assertEquals(expected, Lists.newArrayList(testRange.toSubnets())); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_largeTest1() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("a:b:c:d::"), + fromString("a:b:c:e::")); + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + @Test + public void subnets_largeTestAlreadyANetwork() + { + IPv6AddressRange testRange = fromFirstAndLast(fromString("a:b:c:c::"), fromString("a:b:c:f:ffff:ffff:ffff:ffff")); + IPv6Network network = IPv6Network.fromTwoAddresses(testRange.getFirst(), testRange.getLast()); + assertEquals(testRange, network); // just to prove that the range is already a network + checkSubnetsSameAsRange(testRange.toSubnets(), testRange); + } + + /** + * Check that a given list of subnets denotes exactly the same addresses as a given range. + */ + private void checkSubnetsSameAsRange(Iterator subnets, IPv6AddressRange range) + { + IPv6Network current = subnets.next(); + + // first + assertEquals(range.getFirst(), current.getFirst()); + + // networks should be non overlapping and consecutive + while (subnets.hasNext()) + { + IPv6Network prev = current; + current = subnets.next(); + assertEquals(prev.getLast().add(1), current.getFirst()); + } + + // last + assertEquals(range.getLast(), current.getLast()); + } + +} diff --git a/trunk/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java b/trunk/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java new file mode 100644 index 0000000..66798ac --- /dev/null +++ b/trunk/src/test/java/com/googlecode/ipv6/IPv6AddressTest.java @@ -0,0 +1,427 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.math.BigInteger; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromInetAddress; +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.*; + +/** + * @author Jan Van Besien + */ +public class IPv6AddressTest +{ + @Test + public void parseFromAllZeroes() + { + assertEquals("::", fromString("0000:0000:0000:0000:0000:0000:0000:0000").toString()); + } + + @Test + public void parseFromAllZeroesShortNotation() + { + assertEquals("::", fromString("::").toString()); + } + + @Test + public void parseSomeRealAddresses() + { + assertEquals("::1", fromString("0000:0000:0000:0000:0000:0000:0000:0001").toString()); + assertEquals("::1:0", fromString("0000:0000:0000:0000:0000:0000:0001:0000").toString()); + assertEquals("1::1:0:0:0", fromString("0001:0000:0000:0000:0001:0000:0000:0000").toString()); + assertEquals("::ffff", fromString("0000:0000:0000:0000:0000:0000:0000:ffff").toString()); + assertEquals("ffff::", fromString("ffff:0000:0000:0000:0000:0000:0000:0000").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesShortNotation() + { + assertEquals("::1", fromString("::1").toString()); + assertEquals("::1:0", fromString("::1:0").toString()); + assertEquals("1::1:0:0:0", fromString("1::1:0:0:0").toString()); + assertEquals("::ffff", fromString("::ffff").toString()); + assertEquals("ffff::", fromString("ffff::").toString()); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toString()); + } + + @Test + public void parseSomeRealAddressesFromRFC5952() + { + assertEquals("::", fromString("::").toString()); + assertEquals("1:2:3:4::", fromString("1:2:3:4::").toString()); + assertEquals("::1:2:3:4", fromString("::1:2:3:4").toString()); + assertEquals("1::2", fromString("1::2").toString()); + assertEquals("::2", fromString("::2").toString()); + assertEquals("1::", fromString("1::").toString()); + assertEquals("a31:200:3abc::de4", fromString("0a31:0200:3AbC::0dE4").toString()); + assertEquals("1::4:0:0:0", fromString("1:0:0:0:4:0:0:0").toString()); + + assertEquals("2001:db8::1", fromString("2001:db8::1").toString()); + assertEquals("2001:db8::2:1", fromString("2001:db8:0:0:0:0:2:1").toString()); + assertEquals("2001:db8:0:1:1:1:1:1", fromString("2001:db8:0:1:1:1:1:1").toString()); + assertEquals("2001:db8::1:0:0:1", fromString("2001:db8::1:0:0:1").toString()); + assertEquals("2001:0:0:1::1", fromString("2001:0:0:1:0:0:0:1").toString()); + + assertEquals("1:0:0:4::", fromString("1:0:0:4::").toString()); + } + + @Test + public void parseSomeRealIPv4MappedAddresses() + { + assertEquals("::ffff:0.0.0.1", fromString("::ffff:0.0.0.1").toString()); + assertEquals("::ffff:192.168.139.50", fromString("::ffff:192.168.139.50").toString()); + assertEquals("::ffff:192.168.139.50", fromString("::ffff:c0a8:8b32").toString()); + } + + @Test + public void toLongStringOnSomeRealAddresses() + { + assertEquals("0000:0000:0000:0000:0000:0000:0000:0001", fromString("::1").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0001:0000", fromString("::1:0").toLongString()); + assertEquals("0001:0000:0000:0000:0001:0000:0000:0000", fromString("1::1:0:0:0").toLongString()); + assertEquals("0000:0000:0000:0000:0000:0000:0000:ffff", fromString("::ffff").toLongString()); + assertEquals("ffff:0000:0000:0000:0000:0000:0000:0000", fromString("ffff::").toLongString()); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", fromString("2001:db8:85a3::8a2e:370:7334").toLongString()); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_1() + { + fromString(":"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalid_2() + { + fromString(":a"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_1() + { + fromString("a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooShort_2() + { + fromString("a:a:"); + } + + @Test(expected = IllegalArgumentException.class) + public void parseInvalidTooLong() + { + fromString("a:a:a:a:a:a:a:a:a:a:a:a"); + } + + @Test + public void constructFromInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals("2001:db8:85a3::8a2e:370:7334", fromInetAddress(inetAddress).toString()); + } + + @Test + public void convertToInet6Address() throws UnknownHostException + { + final InetAddress inetAddress = Inet6Address.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + assertEquals(inetAddress, fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").toInetAddress()); + } + + @Test + public void constructFromByteArray() throws UnknownHostException + { + assertEquals("1:1:1:1:1:1:1:1", + IPv6Address.fromByteArray( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}) + .toString()); + } + + @Test + public void convertToByteArray() throws UnknownHostException + { + assertArrayEquals( + new byte[]{0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}, + fromString("1:1:1:1:1:1:1:1").toByteArray()); + } + + @Test + public void convertToAndFromByteArray() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + byte[] randomBytes = new byte[16]; + rg.nextBytes(randomBytes); + + final IPv6Address address = IPv6Address.fromByteArray(randomBytes); + assertArrayEquals(randomBytes, address.toByteArray()); + } + } + + @Test + public void convertToBigInteger() throws UnknownHostException + { + assertEquals(BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE), IPv6Address.MAX.toBigInteger()); + assertEquals(BigInteger.ONE.shiftLeft(128).subtract(BigInteger.valueOf(16)), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0").toBigInteger()); + } + + @Test + public void convertToAndFromBigInteger() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + byte[] randomBytes = new byte[16]; + rg.nextBytes(randomBytes); + BigInteger randomBigInteger = new BigInteger(1, randomBytes); + + final IPv6Address address = IPv6Address.fromBigInteger(randomBigInteger); + assertEquals(randomBigInteger, address.toBigInteger()); + } + } + + @Test + public void positionOfLongestRunOfZeroes() + { + assertArrayEquals(new int[]{0, 8}, fromString("::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{3, 5}, fromString("a:b:c::").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{2, 5}, fromString("a:b::c").startAndLengthOfLongestRunOfZeroes()); + assertArrayEquals(new int[]{4, 4}, fromString("a:0:0:c::").startAndLengthOfLongestRunOfZeroes()); + } + + @Test + public void toStringCompactsLongestRunOfZeroes() + { + assertEquals("0:0:1::", fromString("0:0:1::").toString()); // and not ::1:0:0:0:0:0 + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Address address = new IPv6Address(rg.nextLong(), rg.nextLong()); + assertEquals(address, fromString(address.toString())); + } + } + + @Test + public void addition() + { + assertEquals(fromString("::2"), fromString("::1").add(1)); + assertEquals(fromString("::1:0:0:0"), fromString("::ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:0"), fromString("::ffff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::1:0:0:0:1"), fromString("::ffff:ffff:ffff:ffff").add(2)); + assertEquals(fromString("::8000:0:0:0"), fromString("::7fff:ffff:ffff:ffff").add(1)); + assertEquals(fromString("::").add(Integer.MAX_VALUE).add(Integer.MAX_VALUE), fromString("::").add(Integer.MAX_VALUE).add( + Integer.MAX_VALUE)); + } + + @Test + public void additionOverflow() + { + assertEquals(fromString("::"), fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").add(1)); + } + + @Test + public void subtraction() + { + assertEquals(fromString("::1"), fromString("::2").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:ffff"), fromString("::0001:0:0:0:0").subtract(1)); + assertEquals(fromString("::ffff:ffff:ffff:fffe"), fromString("::0001:0:0:0:0").subtract(2)); + assertEquals(fromString("::7fff:ffff:ffff:ffff"), fromString("::8000:0:0:0").subtract(1)); + assertEquals(fromString("::").subtract(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE), fromString("::").subtract( + Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + } + + @Test + public void subtractionVersusAdditionWithRandomAddresses() + { + final Random random = new Random(); + final int randomInt = random.nextInt(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(randomInt).subtract(randomInt)); + } + + @Test + public void subtractionVersusAdditionCornerCases() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + assertEquals(randomAddress, randomAddress.add(Integer.MAX_VALUE).subtract(Integer.MAX_VALUE)); + assertEquals(randomAddress, randomAddress.add(Integer.MIN_VALUE).subtract(Integer.MIN_VALUE)); + } + + @Test + public void subtractionUnderflow() + { + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), fromString("::").subtract(1)); + } + + @Test + public void setBit() + { + assertEquals(fromString("::1"), fromString("::").setBit(0)); + assertEquals(fromString("::2"), fromString("::").setBit(1)); + assertEquals(fromString("::3"), fromString("::").setBit(0).setBit(1)); + + assertEquals(fromString("0:0:0:1::"), fromString("::").setBit(64)); + assertEquals(fromString("0:0:0:2::"), fromString("::").setBit(65)); + } + + @Test + public void compare() + { + assertTrue(0 == fromString("::").compareTo(fromString("::"))); + assertTrue(0 > fromString("::").compareTo(fromString("::1"))); + assertTrue(0 < fromString("::1").compareTo(fromString("::"))); + + assertTrue(0 > fromString("::").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("::efff:ffff:ffff:ffff").compareTo(fromString("::ffff:ffff:ffff:ffff"))); + assertTrue(0 > fromString("efff:ffff:ffff:ffff:0:1:2:3").compareTo(fromString("ffff:ffff:ffff:ffff:4:5:6:7"))); + } + + @Test + public void maskWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("2000::"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maskWithNetworkMask(new IPv6NetworkMask(15))); + assertEquals(fromString("8000::"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").maskWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void maximumAddressWithPrefixLength() + { + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(128))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:0000:8a2e:0370:73ff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7300").maximumAddressWithNetworkMask(new IPv6NetworkMask(120))); + assertEquals(fromString("2001:0db8:85a3:0000:ffff:ffff:ffff:ffff"), + fromString("2001:0db8:85a3:0000:0000:8a2e:0370:7334").maximumAddressWithNetworkMask(new IPv6NetworkMask(64))); + assertEquals(fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("8000::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + assertEquals(fromString("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + fromString("7fff::").maximumAddressWithNetworkMask(new IPv6NetworkMask(1))); + } + + @Test + public void numberOfTrailingOnes() + { + assertEquals(0, fromString("::").numberOfTrailingOnes()); + assertEquals(1, fromString("::1").numberOfTrailingOnes()); + assertEquals(4, fromString("::f").numberOfTrailingOnes()); + + final IPv6Address addressWithLowBitsEqualToLongMaxValue = fromString("::7fff:ffff:ffff:ffff"); + assertEquals(Long.MAX_VALUE, addressWithLowBitsEqualToLongMaxValue.getLowBits()); + assertEquals(63, addressWithLowBitsEqualToLongMaxValue.numberOfTrailingOnes()); + } + + @Test + public void numberOfLeadingOnes() + { + assertEquals(0, fromString("::").numberOfLeadingOnes()); + assertEquals(1, fromString("8000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::").numberOfLeadingOnes()); + assertEquals(4, fromString("f000::f").numberOfLeadingOnes()); + assertEquals(65, fromString("ffff:ffff:ffff:ffff:8000::f").numberOfLeadingOnes()); + } + + @Test + public void numberOfTrailingZeroes() + { + assertEquals(128, fromString("::").numberOfTrailingZeroes()); + assertEquals(127, fromString("8000::").numberOfTrailingZeroes()); + assertEquals(124, fromString("f000::").numberOfTrailingZeroes()); + assertEquals(0, fromString("f000::f").numberOfTrailingZeroes()); + assertEquals(63, fromString("ffff:ffff:ffff:ffff:8000::").numberOfTrailingZeroes()); + } + + @Test + public void numberOfLeadingZeroes() + { + assertEquals(128, fromString("::").numberOfLeadingZeroes()); + assertEquals(0, fromString("8000::").numberOfLeadingZeroes()); + assertEquals(124, fromString("::f").numberOfLeadingZeroes()); + assertEquals(63, fromString("::1:ffff:ffff:ffff:ffff").numberOfLeadingZeroes()); + } + + @Test + public void isIPv4Mapped() + { + assertFalse(fromString("::").isIPv4Mapped()); + assertFalse(fromString("::0001:ffff:1234:5678").isIPv4Mapped()); + assertFalse(fromString("1::ffff:1234:5678").isIPv4Mapped()); + assertFalse(fromString("::afff:1234:5678").isIPv4Mapped()); + + assertTrue(fromString("::ffff:1234:5678").isIPv4Mapped()); + assertTrue(fromString("::ffff:192.168.123.123").isIPv4Mapped()); + } + + @Test + public void isMulticast() + { + assertFalse(fromString("::").isMulticast()); + + assertTrue(fromString("ff12::ffff:1234:5678").isMulticast()); + } + + @Test + public void isLinkLocal() + { + assertFalse(fromString("::").isLinkLocal()); + + assertTrue(fromString("fe80::ffff:1234:5678").isLinkLocal()); + } + + @Test + public void isSiteLocal() + { + assertFalse(fromString("::").isSiteLocal()); + + assertTrue(fromString("fec0::ffff:1234:5678").isSiteLocal()); + } + +} diff --git a/trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java b/trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java new file mode 100644 index 0000000..960d630 --- /dev/null +++ b/trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkHelpersTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static junit.framework.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkHelpersTest +{ + @Test + public void longestPrefixLength() + { + assertEquals(128, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("::1"))); + assertEquals(127, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::"))); + assertEquals(126, IPv6NetworkHelpers.longestPrefixLength(fromString("::1"), fromString("::2"))); + + assertEquals(0, IPv6NetworkHelpers.longestPrefixLength(fromString("::"), fromString("ffff::"))); + assertEquals(32, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::"), fromString("ffff:ffff:8000::"))); + assertEquals(65, IPv6NetworkHelpers.longestPrefixLength(fromString("ffff:ffff::8000:2:3:4"), fromString("ffff:ffff::C000:2:3:4"))); + } +} diff --git a/trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java b/trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java new file mode 100644 index 0000000..0eea592 --- /dev/null +++ b/trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkMaskTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkMaskTest +{ + @Test + public void constructValidNetworkMasks() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), new IPv6NetworkMask(128)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), new IPv6NetworkMask(127)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffcL)), new IPv6NetworkMask(126)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), new IPv6NetworkMask(65)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), new IPv6NetworkMask(64)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xc000000000000000L, 0x0L)), new IPv6NetworkMask(2)); + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), new IPv6NetworkMask(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_Negative() + { + new IPv6NetworkMask(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromPrefixLength_TooBig() + { + new IPv6NetworkMask(129); + } + + @Test(expected = IllegalArgumentException.class) + public void constructInvalidFromAddress() + { + IPv6NetworkMask.fromAddress(new IPv6Address(123L, 456L)); + } + +} diff --git a/trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java b/trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java new file mode 100644 index 0000000..21d9e61 --- /dev/null +++ b/trunk/src/test/java/com/googlecode/ipv6/IPv6NetworkTest.java @@ -0,0 +1,190 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6; + +import org.junit.Test; + +import java.util.Iterator; +import java.util.Random; + +import static com.googlecode.ipv6.IPv6Address.fromString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Jan Van Besien + */ +public class IPv6NetworkTest +{ + @Test + public void constructFromTwoAddresses() + { + assertEquals(IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)), + IPv6Network.fromTwoAddresses(fromString("::1"), fromString("::2"))); + assertEquals(IPv6Network.fromAddressAndMask(fromString("a:b::"), IPv6NetworkMask.fromPrefixLength(44)), + IPv6Network.fromTwoAddresses(fromString("a:b:c::1:1"), fromString("a:b::f:f"))); + } + + @Test + public void stringRepresentation() + { + assertEquals("::/126", IPv6Network.fromAddressAndMask(fromString("::"), IPv6NetworkMask.fromPrefixLength(126)).toString()); + assertEquals("a:b:c:d::/64", IPv6Network.fromAddressAndMask(fromString("a:b:c:d::"), IPv6NetworkMask.fromPrefixLength(64)) + .toString()); + } + + @Test + public void toStringCanBeUsedInFromStringAndViceVersa() + { + final int nTests = 10000; + final Random rg = new Random(); + + for (int i = 0; i < nTests; i++) + { + final IPv6Network network = IPv6Network.fromAddressAndMask(new IPv6Address(rg.nextLong(), rg.nextLong()), + IPv6NetworkMask.fromPrefixLength(rg.nextInt(128) + 1)); + assertEquals(network, IPv6Network.fromString(network.toString())); + } + } + + @Test + public void constructAndVerifyPrefixLength() + { + assertEquals(1, IPv6Network.fromString("a:b:c::/1").getNetmask().asPrefixLength()); + assertEquals(63, IPv6Network.fromString("a:b:c::/63").getNetmask().asPrefixLength()); + assertEquals(64, IPv6Network.fromString("a:b:c::/64").getNetmask().asPrefixLength()); + assertEquals(65, IPv6Network.fromString("a:b:c::/65").getNetmask().asPrefixLength()); + assertEquals(127, IPv6Network.fromString("a:b:c::/127").getNetmask().asPrefixLength()); + assertEquals(128, IPv6Network.fromString("a:b:c::/128").getNetmask().asPrefixLength()); + } + + @Test + public void constructAndVerifyNetmask() + { + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0x8000000000000000L, 0x0L)), + IPv6Network.fromString("a:b:c::/1").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xfffffffffffffffeL, 0x0L)), + IPv6Network.fromString("a:b:c::/63").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x0L)), + IPv6Network.fromString("a:b:c::/64").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0x8000000000000000L)), + IPv6Network.fromString("a:b:c::/65").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xfffffffffffffffeL)), + IPv6Network.fromString("a:b:c::/127").getNetmask()); + + assertEquals(IPv6NetworkMask.fromAddress(new IPv6Address(0xffffffffffffffffL, 0xffffffffffffffffL)), + IPv6Network.fromString("a:b:c::/128").getNetmask()); + } + + @Test + public void contains() + { + assertTrue(IPv6Network.fromString("ffff::/8").contains(IPv6Address.fromString("ffff::1"))); + assertTrue(IPv6Network.fromString("1234:5678:1234:5678::/64").contains(IPv6Address.fromString("1234:5678:1234:5678:1::"))); + } + + @Test + public void zeroNetworkContainsEverything() + { + final Random random = new Random(); + final IPv6Address randomAddress = new IPv6Address(random.nextLong(), random.nextLong()); + + assertTrue(IPv6Network.fromString("::/0").contains(randomAddress)); + assertTrue(IPv6Network.fromString("abcd:effe:dcba::/0").contains(randomAddress)); + } + + @Test + public void iteratorShouldStartWithFirstAndEndWithLast() + { + IPv6Network ipv6Network = IPv6Network.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0000/126"); + Iterator iterator = ipv6Network.iterator(); + int i = 0; + for (; iterator.hasNext(); i++) + { + assertEquals(IPv6Address.fromString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:000" + i), iterator.next()); + } + assertEquals(4, i); + } + + @Test + public void split() + { + { + IPv6Network slash120 = IPv6Network.fromString("::ffff:192.168.123.0/120"); + Iterator splits = slash120.split(IPv6NetworkMask.fromPrefixLength(121)); + verifySplits(splits, 2, IPv6Network.fromString("::ffff:192.168.123.0/121"), + IPv6Network.fromString("::ffff:192.168.123.128/121")); + } + + { + IPv6Network slash30 = IPv6Network.fromString("a:b:c:d:1:2:3:4/30"); // a:8:: is the host address after masking with /30 + Iterator splits = slash30.split(IPv6NetworkMask.fromPrefixLength(40)); + verifySplits(splits, (int) Math.pow(2, 40 - 30), + IPv6Network.fromString("a:8::/40"), + IPv6Network.fromString("a:8:100::/40"), + IPv6Network.fromString("a:8:200::/40")); + } + } + + @Test(expected = IllegalArgumentException.class) + public void splitInLargerSize() + { + IPv6Network ipv6Network = IPv6Network.fromString("1:2:3:4:5:6:7:8/69"); + ipv6Network.split(IPv6NetworkMask.fromPrefixLength(68)); // 68 subnet is bigger than 69 + } + + @Test + public void splitInSameSize() + { + IPv6Network ipv6Network = IPv6Network.fromString("1:2:3:4:5:6:7:8/69"); + Iterator splits = ipv6Network.split(IPv6NetworkMask.fromPrefixLength(69)); + verifySplits(splits, 1, ipv6Network); + } + + /** + * Verify a splitted network. + * + * @param splits splits to verify + * @param expectedNbr number of expected splits + * @param expectedSplits the first splits in the list to expect (check as many as you want but no need to check them all) + */ + private void verifySplits(Iterator splits, int expectedNbr, IPv6Network... expectedSplits) + { + int nChecked = 0; + + // check the ones that are explicitely passed + for (IPv6Network expectedSplit : expectedSplits) + { + assertEquals(expectedSplit, splits.next()); + nChecked++; + } + + // merely check count for the others + while (splits.hasNext()) + { + splits.next(); + nChecked++; + } + + assertEquals(expectedNbr, nChecked); + } + +} diff --git a/trunk/src/test/java/com/googlecode/ipv6/examples/Examples.java b/trunk/src/test/java/com/googlecode/ipv6/examples/Examples.java new file mode 100644 index 0000000..25f69d9 --- /dev/null +++ b/trunk/src/test/java/com/googlecode/ipv6/examples/Examples.java @@ -0,0 +1,152 @@ +/* + * Copyright 2013 Jan Van Besien + * + * 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. + */ + +package com.googlecode.ipv6.examples; + +import com.googlecode.ipv6.*; +import org.junit.Test; + +import java.util.Iterator; + +/** + * Some examples also featured in the online documentation. This class is in a separate package on purpose, such that we make sure only to + * call methods of the public API. + * + * @author Jan Van Besien + */ +public class Examples +{ + @Test + public void ipAddressConstruction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address iPv4MappedIPv6Address = IPv6Address.fromString("::ffff:192.168.0.1"); + } + + @Test + public void ipAddressAdditionAndSubtraction() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + final IPv6Address next = iPv6Address.add(1); + final IPv6Address previous = iPv6Address.subtract(1); + System.out.println(next.toString()); // prints fe80::226:2dff:fefa:cd20 + System.out.println(previous.toString()); // prints fe80::226:2dff:fefa:cd1e + } + + @Test + public void ipAddressRangeConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + System.out.println(range.contains(IPv6Address.fromString("fe80::226:2dff:fefa:dcba"))); // prints true + } + + @Test + public void ipAddressRangeConvertToSubnets() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("::1:ffcc"), + IPv6Address.fromString("::2:0")); + + Iterator subnetsIterator = range.toSubnets(); + while (subnetsIterator.hasNext()) + System.out.println(subnetsIterator.next()); + + // prints ::1:ffcc/126 ::1:ffd0/124 ::1:ffe0/123 ::2:0/128 (i.e. the minimal set of networks that define the original range) + } + + @Test + public void ipNetworkConstruction() + { + final IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")); + final IPv6Network network = IPv6Network.fromString("fe80::226:2dff:fefa:0/112"); + System.out.println(range.equals(network)); // prints true + } + + @Test + public void ipNetworkCalculation() + { + final IPv6Network strangeNetwork = IPv6Network.fromString("fe80::226:2dff:fefa:cd1f/43"); + + System.out.println(strangeNetwork.getFirst()); // prints fe80:: + System.out.println(strangeNetwork.getLast()); // prints fe80:0:1f:ffff:ffff:ffff:ffff:ffff + System.out.println(strangeNetwork.getNetmask().asPrefixLength()); // prints 43 + System.out.println(strangeNetwork.getNetmask().asAddress()); // prints ffff:ffff:ffe0:: + } + + @Test + public void ipNetworkSplitInSmallerSubnets() + { + final IPv6Network network = IPv6Network.fromString("1:2:3:4:5:6:7:0/120"); + + Iterator splits = network.split(IPv6NetworkMask.fromPrefixLength(124)); + while (splits.hasNext()) + System.out.println(splits.next()); + + // prints 1:2:3:4:5:6:7:0/124, 1:2:3:4:5:6:7:10/124, 1:2:3:4:5:6:7:20/124, ... until 1:2:3:4:5:6:7:f0/124 (16 in total) + } + + @Test + public void ipNetworkNotationChoices() + { + IPv6Network prefixLengthNotation = IPv6Network.fromString("::1/16"); + IPv6Network addressNotation = + IPv6Network.fromAddressAndMask(IPv6Address.fromString("::"), IPv6NetworkMask.fromAddress(IPv6Address.fromString("ffff::"))); + System.out.println(prefixLengthNotation.equals(addressNotation)); // prints true + System.out.println(prefixLengthNotation); // prints ::/16 + System.out.println(prefixLengthNotation.getFirst() + "/" + prefixLengthNotation.getNetmask().asAddress()); // prints ::/ffff:: + } + + @Test(expected = IllegalArgumentException.class) + public void ipNetworkMaskConstruction() + { + final IPv6NetworkMask slash40Network = IPv6NetworkMask.fromPrefixLength(40); + System.out.println(slash40Network.asAddress()); // prints ffff:ffff:ff00:: + System.out.println(slash40Network.asPrefixLength()); // prints 40 + + final IPv6NetworkMask slash40NetworkConstructedFromAddressNotation = IPv6NetworkMask.fromAddress( + IPv6Address.fromString("ffff:ffff:ff00::")); + System.out.println(slash40Network.equals(slash40NetworkConstructedFromAddressNotation)); // prints true + + final IPv6NetworkMask invalidNetworkMask = IPv6NetworkMask.fromAddress(IPv6Address.fromString("0fff::")); // fails + } + + @Test + public void ipAddressNetworkMasking() + { + final IPv6Address iPv6Address = IPv6Address.fromString("fe80::226:2dff:fefa:cd1f"); + + final IPv6Address masked = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(masked.toString()); // prints fe80:: + + final IPv6Address maximum = iPv6Address.maximumAddressWithNetworkMask(IPv6NetworkMask.fromPrefixLength(40)); + System.out.println(maximum.toString()); // prints fe80:0:ff:ffff:ffff:ffff:ffff:ffff + } + + @Test + public void poolExample() + { + final IPv6AddressPool pool = IPv6AddressPool.fromRangeAndSubnet( + IPv6AddressRange.fromFirstAndLast(IPv6Address.fromString("fe80::226:2dff:fefa:0"), + IPv6Address.fromString("fe80::226:2dff:fefa:ffff")), + IPv6NetworkMask.fromPrefixLength(120)); + System.out.println(pool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints true + + final IPv6AddressPool newPool = pool.allocate(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120")); + System.out.println(newPool.isFree(IPv6Network.fromString("fe80::226:2dff:fefa:5ff/120"))); // prints false + } + +} diff --git a/trunk/target/apidocs/allclasses-frame.html b/trunk/target/apidocs/allclasses-frame.html new file mode 100644 index 0000000..e7cd6a1 --- /dev/null +++ b/trunk/target/apidocs/allclasses-frame.html @@ -0,0 +1,25 @@ + + + + + + +所有类 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + +

所有类

+ + + diff --git a/trunk/target/apidocs/allclasses-noframe.html b/trunk/target/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..9e0bb02 --- /dev/null +++ b/trunk/target/apidocs/allclasses-noframe.html @@ -0,0 +1,25 @@ + + + + + + +所有类 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + +

所有类

+ + + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/IPv6Address.html b/trunk/target/apidocs/com/googlecode/ipv6/IPv6Address.html new file mode 100644 index 0000000..c417234 --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/IPv6Address.html @@ -0,0 +1,707 @@ + + + + + + +IPv6Address (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

类 IPv6Address

+
+
+ +
+ +
+
+ +
+
+
    +
  • + + + +
      +
    • + + +

      方法详细资料

      + + + +
        +
      • +

        fromLongs

        +
        public static IPv6Address fromLongs(long highBits,
        +                    long lowBits)
        +
        Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits. It is usually easier to construct + IPv6Addresses from a String or an InetAddress. The internal representation of an IPv6Address is exactly + these two longs though, so if you already happen to have them, this provides a very efficient way to construct an IPv6Address.
        +
        参数:
        highBits - highest order bits
        lowBits - lowest order bits
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Address fromString(String string)
        +
        Create an IPv6 address from its String representation. For example "1234:5678:abcd:0000:9876:3210:ffff:ffff" or "2001::ff" or even + "::". IPv4-Mapped IPv6 addresses such as "::ffff:123.456.123.456" are also supported.
        +
        参数:
        string - string representation
        +
        返回:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        fromInetAddress

        +
        public static IPv6Address fromInetAddress(InetAddress inetAddress)
        +
        Create an IPv6 address from a java.net.Inet6Address.
        +
        参数:
        inetAddress - Inet6Address representation
        +
        返回:
        IPv6 address
        +
      • +
      + + + + + + + +
        +
      • +

        fromByteArray

        +
        public static IPv6Address fromByteArray(byte[] bytes)
        +
        Create an IPv6 address from a byte array.
        +
        参数:
        bytes - byte array with 16 bytes (interpreted unsigned)
        +
        返回:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        toByteArray

        +
        public byte[] toByteArray()
        +
        返回:
        byte[] representation
        +
      • +
      + + + +
        +
      • +

        fromBigInteger

        +
        public static IPv6Address fromBigInteger(BigInteger bigInteger)
        +
        Create an IPv6 address from a (positive) BigInteger. The magnitude of the BigInteger represents + the IPv6 address value. Or in other words, the BigInteger with value N defines the Nth possible IPv6 address.
        +
        参数:
        bigInteger - BigInteger value
        +
        返回:
        IPv6 address
        +
      • +
      + + + +
        +
      • +

        toBigInteger

        +
        public BigInteger toBigInteger()
        +
        返回:
        BigInteger representation. The magnitude of the BigInteger represents the IPv6 address + value. Or in other words, the BigInteger with value N defines the Nth possible IPv6 address.
        +
      • +
      + + + +
        +
      • +

        add

        +
        public IPv6Address add(int value)
        +
        Addition. Will never overflow, but wraps around when the highest ip address has been reached.
        +
        参数:
        value - value to add
        +
        返回:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        subtract

        +
        public IPv6Address subtract(int value)
        +
        Subtraction. Will never underflow, but wraps around when the lowest ip address has been reached.
        +
        参数:
        value - value to substract
        +
        返回:
        new IPv6 address
        +
      • +
      + + + +
        +
      • +

        maskWithNetworkMask

        +
        public IPv6Address maskWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Mask the address with the given network mask.
        +
        参数:
        networkMask - network mask
        +
        返回:
        an address of which the last 128 - networkMask.asPrefixLength() bits are zero
        +
      • +
      + + + +
        +
      • +

        maximumAddressWithNetworkMask

        +
        public IPv6Address maximumAddressWithNetworkMask(IPv6NetworkMask networkMask)
        +
        Calculate the maximum address with the given network mask.
        +
        参数:
        networkMask - network mask
        +
        返回:
        an address of which the last 128 - networkMask.asPrefixLength() bits are one
        +
      • +
      + + + +
        +
      • +

        setBit

        +
        public IPv6Address setBit(int bit)
        +
        Set a bit in the address.
        +
        参数:
        bit - to set (in the range [0, 127])
        +
        返回:
        an address with the given bit set
        +
      • +
      + + + +
        +
      • +

        isIPv4Mapped

        +
        public boolean isIPv4Mapped()
        +
        Returns true if the address is an IPv4-mapped IPv6 address. In these addresses, the first 80 bits are zero, the next 16 bits are one, + and the remaining 32 bits are the IPv4 address.
        +
        返回:
        true if the address is an IPv4-mapped IPv6 addresses.
        +
      • +
      + + + +
        +
      • +

        isMulticast

        +
        public boolean isMulticast()
        +
        返回:
        true if the address is an IPv6 multicast address (an address in the network ff00::/8)
        +
      • +
      + + + +
        +
      • +

        isSiteLocal

        +
        public boolean isSiteLocal()
        +
        返回:
        true if the address is an IPv6 site-local address (an address in the network fec0::/48)
        +
      • +
      + + + +
        +
      • +

        isLinkLocal

        +
        public boolean isLinkLocal()
        +
        返回:
        true if the address is an IPv6 link-local address (an address in the network fe80::/48)
        +
      • +
      + + + +
        +
      • +

        toString

        +
        public String toString()
        +
        Returns a string representation of the IPv6 address. It will use shorthand notation and special notation for IPv4-mapped IPv6 + addresses whenever possible.
        +
        +
        覆盖:
        +
        toString 在类中 Object
        +
        返回:
        String representation of the IPv6 address
        +
      • +
      + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        返回:
        String representation of the IPv6 address, never using shorthand notation.
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        覆盖:
        +
        equals 在类中 Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        覆盖:
        +
        hashCode 在类中 Object
        +
        +
      • +
      + + + + + + + +
        +
      • +

        getHighBits

        +
        public long getHighBits()
        +
      • +
      + + + +
        +
      • +

        getLowBits

        +
        public long getLowBits()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingZeroes

        +
        public int numberOfTrailingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfTrailingOnes

        +
        public int numberOfTrailingOnes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingZeroes

        +
        public int numberOfLeadingZeroes()
        +
      • +
      + + + +
        +
      • +

        numberOfLeadingOnes

        +
        public int numberOfLeadingOnes()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html b/trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html new file mode 100644 index 0000000..4829175 --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressHelpers.html @@ -0,0 +1,274 @@ + + + + + + +IPv6AddressHelpers (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

类 IPv6AddressHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressHelpers
    +extends Object
    +
    Helper methods used by IPv6Address.
    +
    作者:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      构造器详细资料

      + + + +
        +
      • +

        IPv6AddressHelpers

        +
        public IPv6AddressHelpers()
        +
      • +
      +
    • +
    + +
      +
    • + + +

      方法详细资料

      + + + +
        +
      • +

        countOccurrences

        +
        public static int countOccurrences(String haystack,
        +                   char needle)
        +
      • +
      + + + +
        +
      • +

        generateZeroes

        +
        public static String generateZeroes(int number)
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressPool.html b/trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressPool.html new file mode 100644 index 0000000..76df61d --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressPool.html @@ -0,0 +1,474 @@ + + + + + + +IPv6AddressPool (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

类 IPv6AddressPool

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6AddressPool
    +extends Object
    +
    Immutable representation of an IPv6 address pool. +

    + An IPv6 address pool is like an IPv6 address range in which some addresses are "free" and some are "allocated". Think "dhcp server". + Addresses are allocated in whole subnet blocks at once. These subnet blocks have a predefined prefix length for the whole allocatable + range.

    +
    作者:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      方法详细资料

      + + + +
        +
      • +

        fromRangeAndSubnet

        +
        public static IPv6AddressPool fromRangeAndSubnet(IPv6AddressRange range,
        +                                 IPv6NetworkMask allocationSubnetSize)
        +
        Create a pool of the given range (boundaries inclusive) which is completely free. The given subnet size is the network mask (thus + size) of the allocated subnets in this range. This constructor verifies that the whole range is "aligned" with subnets of this size + (i.e. there should not be a waste of space in the beginning or end which is smaller than one subnet of the given subnet size).
        +
        参数:
        range - range from within to allocate
        allocationSubnetSize - size of the subnets that will be allocated
        +
      • +
      + + + +
        +
      • +

        getLastAllocated

        +
        public IPv6Network getLastAllocated()
        +
        返回:
        the last IPv6Network which was allocated or null if none was allocated yet
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate()
        +
        Allocate the first available subnet from the pool.
        +
        返回:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        allocate

        +
        public IPv6AddressPool allocate(IPv6Network toAllocate)
        +
        Allocate the given subnet from the pool.
        +
        参数:
        toAllocate - subnet to allocate from the pool
        +
        返回:
        resulting pool
        +
      • +
      + + + +
        +
      • +

        deAllocate

        +
        public IPv6AddressPool deAllocate(IPv6Network toDeAllocate)
        +
        Give a network back to the pool (de-allocate).
        +
        参数:
        toDeAllocate - network to de-allocate
        +
      • +
      + + + +
        +
      • +

        isExhausted

        +
        public boolean isExhausted()
        +
        返回:
        true if no subnets are free in this pool, false otherwize
        +
      • +
      + + + +
        +
      • +

        isFree

        +
        public boolean isFree(IPv6Network network)
        +
      • +
      + + + +
        +
      • +

        freeNetworks

        +
        public Iterable<IPv6Network> freeNetworks()
        +
        返回:
        all networks (all with the same fixed prefix length) which are free in this pool
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        覆盖:
        +
        equals 在类中 Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        覆盖:
        +
        hashCode 在类中 Object
        +
        +
      • +
      + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        返回:
        like toString but without using shorthand notations for addresses
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressRange.html b/trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressRange.html new file mode 100644 index 0000000..b65aadd --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/IPv6AddressRange.html @@ -0,0 +1,500 @@ + + + + + + +IPv6AddressRange (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

类 IPv6AddressRange

+
+
+ +
+ +
+
+ +
+
+
    +
  • + +
      +
    • + + +

      方法详细资料

      + + + + + + + +
        +
      • +

        contains

        +
        public boolean contains(IPv6Address address)
        +
      • +
      + + + + + + + + + + + + + + + +
        +
      • +

        size

        +
        public BigInteger size()
        +
        返回:
        number of addresses in the range
        +
      • +
      + + + +
        +
      • +

        toSubnets

        +
        public Iterator<IPv6Network> toSubnets()
        +
        Deaggregate a range of IPv6 addresses (which is not necessarily aligned with a single IPv6 network) into a minimal set of non + overlapping consecutive subnets.
        +
        返回:
        iterator of IPv6 networks that all together define the minimal set of subnets by which the range can be represented.
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Address address)
        +
        Remove an address from the range, resulting in one, none or two new ranges. If an address outside the range is removed, this has no + effect. If the first or last address is removed, a single new range is returned (potentially empty if the range only contained a + single address). If an address somewhere else in the range is removed, two new ranges are returned.
        +
        参数:
        address - adddress to remove from the range
        +
        返回:
        list of resulting ranges
        +
      • +
      + + + +
        +
      • +

        extend

        +
        public IPv6AddressRange extend(IPv6Address address)
        +
        Extend the range just enough at its head or tail such that the given address is included.
        +
        参数:
        address - address to extend the range to
        +
        返回:
        new (bigger) range
        +
      • +
      + + + +
        +
      • +

        remove

        +
        public List<IPv6AddressRange> remove(IPv6Network network)
        +
        Remove a network from the range, resulting in one, none or two new ranges. If a network outside (or partially outside) the range is + removed, this has no effect. If the network which is removed is aligned with the beginning or end of the range, a single new ranges + is returned (potentially empty if the range was equal to the network which is removed from it). If a network somewhere else in the + range is removed, two new ranges are returned.
        +
        参数:
        network - network to remove from the range
        +
        返回:
        list of resulting ranges
        +
      • +
      + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        返回:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + +
        +
      • +

        compareTo

        +
        public int compareTo(IPv6AddressRange that)
        +
        The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal. +

        + Note that the natural order does thus not compare sizes of ranges.

        +
        +
        指定者:
        +
        compareTo 在接口中 Comparable<IPv6AddressRange>
        +
        参数:
        that - range to compare with
        +
        返回:
        negative, zero or positive depending on whether this is smaller, equal or greater than that
        +
      • +
      + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        覆盖:
        +
        equals 在类中 Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        覆盖:
        +
        hashCode 在类中 Object
        +
        +
      • +
      + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/IPv6Network.html b/trunk/target/apidocs/com/googlecode/ipv6/IPv6Network.html new file mode 100644 index 0000000..458f819 --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/IPv6Network.html @@ -0,0 +1,450 @@ + + + + + + +IPv6Network (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

类 IPv6Network

+
+
+ +
+
    +
  • +
    +
    所有已实现的接口:
    +
    Comparable<IPv6AddressRange>, Iterable<IPv6Address>
    +
    +
    +
    +
    public final class IPv6Network
    +extends IPv6AddressRange
    +
    Immutable representation of an IPv6 network based on an address and a prefix length. An IPv6 network is also an IPv6 address range (but + not all ranges are valid networks).
    +
    作者:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      字段详细资料

      + + + +
        +
      • +

        MULTICAST_NETWORK

        +
        public static final IPv6Network MULTICAST_NETWORK
        +
      • +
      + + + +
        +
      • +

        SITE_LOCAL_NETWORK

        +
        public static final IPv6Network SITE_LOCAL_NETWORK
        +
      • +
      + + + +
        +
      • +

        LINK_LOCAL_NETWORK

        +
        public static final IPv6Network LINK_LOCAL_NETWORK
        +
      • +
      +
    • +
    + +
      +
    • + + +

      方法详细资料

      + + + +
        +
      • +

        fromAddressAndMask

        +
        public static IPv6Network fromAddressAndMask(IPv6Address address,
        +                             IPv6NetworkMask networkMask)
        +
        Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
        +
        参数:
        address - IPv6 address (the network address or any other address within the network)
        networkMask - IPv6 network mask
        +
        返回:
        IPv6 network
        +
      • +
      + + + +
        +
      • +

        fromTwoAddresses

        +
        public static IPv6Network fromTwoAddresses(IPv6Address one,
        +                           IPv6Address two)
        +
        Create an IPv6 network from the two addresses within the network. This will construct the smallest possible network ("longest prefix + length") which contains both addresses.
        +
        参数:
        one - address one
        two - address two, should be bigger than address one
        +
      • +
      + + + +
        +
      • +

        fromString

        +
        public static IPv6Network fromString(String string)
        +
        Create an IPv6 network from its String representation. For example "1234:5678:abcd:0:0:0:0:0/64" or "2001::ff/128".
        +
        参数:
        string - string representation
        +
        返回:
        IPv6 network
        +
      • +
      + + + + + + + + + + + +
        +
      • +

        toLongString

        +
        public String toLongString()
        +
        +
        覆盖:
        +
        toLongString 在类中 IPv6AddressRange
        +
        返回:
        like toString but without using shorthand notations for addresses
        +
      • +
      + + + + + + + + + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html b/trunk/target/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html new file mode 100644 index 0000000..c312f2a --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/IPv6NetworkHelpers.html @@ -0,0 +1,231 @@ + + + + + + +IPv6NetworkHelpers (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

类 IPv6NetworkHelpers

+
+
+ +
+
    +
  • +
    +
    +
    public class IPv6NetworkHelpers
    +extends Object
    +
    Helper methods used by IPv6Network.
    +
    作者:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      构造器详细资料

      + + + +
        +
      • +

        IPv6NetworkHelpers

        +
        public IPv6NetworkHelpers()
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html b/trunk/target/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html new file mode 100644 index 0000000..3f33608 --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/IPv6NetworkMask.html @@ -0,0 +1,328 @@ + + + + + + +IPv6NetworkMask (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + + +
+
com.googlecode.ipv6
+

类 IPv6NetworkMask

+
+
+ +
+
    +
  • +
    +
    +
    public final class IPv6NetworkMask
    +extends Object
    +
    Immutable representation of an IPv6 network mask. A network mask is nothing more than an IPv6 address with a continuous range of 1 bits + starting from the most significant bit. A network mask can also be represented as a prefix length, which is the count of these 1 bits.
    +
    作者:
    +
    Jan Van Besien
    +
  • +
+
+
+ +
+
+
    +
  • + +
      +
    • + + +

      方法详细资料

      + + + +
        +
      • +

        fromAddress

        +
        public static IPv6NetworkMask fromAddress(IPv6Address iPv6Address)
        +
        Construct an IPv6 network mask from an IPv6 address. The address should be a valid network mask.
        +
        参数:
        iPv6Address - address to use as network mask
        +
        抛出:
        +
        IllegalArgumentException - if the address is not a valid network mask
        +
      • +
      + + + +
        +
      • +

        fromPrefixLength

        +
        public static IPv6NetworkMask fromPrefixLength(int prefixLength)
        +
        Construct an IPv6 network mask from a prefix length. The prefix length should be in the interval ]0, 128].
        +
        参数:
        prefixLength - prefix length
        +
        抛出:
        +
        IllegalArgumentException - if the prefix length is not in the interval ]0, 128]
        +
      • +
      + + + +
        +
      • +

        asPrefixLength

        +
        public int asPrefixLength()
        +
      • +
      + + + + + + + +
        +
      • +

        equals

        +
        public boolean equals(Object o)
        +
        +
        覆盖:
        +
        equals 在类中 Object
        +
        +
      • +
      + + + +
        +
      • +

        hashCode

        +
        public int hashCode()
        +
        +
        覆盖:
        +
        hashCode 在类中 Object
        +
        +
      • +
      + + + + +
    • +
    +
  • +
+
+
+ + + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html new file mode 100644 index 0000000..5b0e256 --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6Address.html @@ -0,0 +1,301 @@ + + + + + + +类 com.googlecode.ipv6.IPv6Address的使用 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + +
+

类 com.googlecode.ipv6.IPv6Address
的使用

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html new file mode 100644 index 0000000..b62d46e --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressHelpers.html @@ -0,0 +1,115 @@ + + + + + + +类 com.googlecode.ipv6.IPv6AddressHelpers的使用 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + +
+

类 com.googlecode.ipv6.IPv6AddressHelpers
的使用

+
+
没有com.googlecode.ipv6.IPv6AddressHelpers的用法
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html new file mode 100644 index 0000000..f90efee --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressPool.html @@ -0,0 +1,161 @@ + + + + + + +类 com.googlecode.ipv6.IPv6AddressPool的使用 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + +
+

类 com.googlecode.ipv6.IPv6AddressPool
的使用

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html new file mode 100644 index 0000000..623dfc8 --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6AddressRange.html @@ -0,0 +1,222 @@ + + + + + + +类 com.googlecode.ipv6.IPv6AddressRange的使用 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + +
+

类 com.googlecode.ipv6.IPv6AddressRange
的使用

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html new file mode 100644 index 0000000..63d14ae --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6Network.html @@ -0,0 +1,238 @@ + + + + + + +类 com.googlecode.ipv6.IPv6Network的使用 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + +
+

类 com.googlecode.ipv6.IPv6Network
的使用

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html new file mode 100644 index 0000000..86ebf42 --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkHelpers.html @@ -0,0 +1,115 @@ + + + + + + +类 com.googlecode.ipv6.IPv6NetworkHelpers的使用 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + +
+

类 com.googlecode.ipv6.IPv6NetworkHelpers
的使用

+
+
没有com.googlecode.ipv6.IPv6NetworkHelpers的用法
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html new file mode 100644 index 0000000..a0c11db --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/class-use/IPv6NetworkMask.html @@ -0,0 +1,193 @@ + + + + + + +类 com.googlecode.ipv6.IPv6NetworkMask的使用 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + +
+

类 com.googlecode.ipv6.IPv6NetworkMask
的使用

+
+
+ +
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/package-frame.html b/trunk/target/apidocs/com/googlecode/ipv6/package-frame.html new file mode 100644 index 0000000..3218de7 --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/package-frame.html @@ -0,0 +1,26 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + +

com.googlecode.ipv6

+ + + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/package-summary.html b/trunk/target/apidocs/com/googlecode/ipv6/package-summary.html new file mode 100644 index 0000000..fc10a28 --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/package-summary.html @@ -0,0 +1,171 @@ + + + + + + +com.googlecode.ipv6 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + + + + +
+

程序包 com.googlecode.ipv6

+
+
+
    +
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    类概要 
    说明
    IPv6Address +
    Immutable representation of an IPv6 address.
    +
    IPv6AddressHelpers +
    Helper methods used by IPv6Address.
    +
    IPv6AddressPool +
    Immutable representation of an IPv6 address pool.
    +
    IPv6AddressRange +
    Immutable representation of a continuous range of IPv6 addresses (bounds included).
    +
    IPv6Network +
    Immutable representation of an IPv6 network based on an address and a prefix length.
    +
    IPv6NetworkHelpers +
    Helper methods used by IPv6Network.
    +
    IPv6NetworkMask +
    Immutable representation of an IPv6 network mask.
    +
    +
  • +
+
+ + + + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/package-tree.html b/trunk/target/apidocs/com/googlecode/ipv6/package-tree.html new file mode 100644 index 0000000..3846c4e --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/package-tree.html @@ -0,0 +1,133 @@ + + + + + + +com.googlecode.ipv6 类分层结构 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

程序包com.googlecode.ipv6的分层结构

+
+
+

类分层结构

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/com/googlecode/ipv6/package-use.html b/trunk/target/apidocs/com/googlecode/ipv6/package-use.html new file mode 100644 index 0000000..67c4aed --- /dev/null +++ b/trunk/target/apidocs/com/googlecode/ipv6/package-use.html @@ -0,0 +1,155 @@ + + + + + + +程序包 com.googlecode.ipv6的使用 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

程序包 com.googlecode.ipv6
的使用

+
+
+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/constant-values.html b/trunk/target/apidocs/constant-values.html new file mode 100644 index 0000000..8285a45 --- /dev/null +++ b/trunk/target/apidocs/constant-values.html @@ -0,0 +1,115 @@ + + + + + + +常量字段值 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

常量字段值

+

目录

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/deprecated-list.html b/trunk/target/apidocs/deprecated-list.html new file mode 100644 index 0000000..1ec4880 --- /dev/null +++ b/trunk/target/apidocs/deprecated-list.html @@ -0,0 +1,115 @@ + + + + + + +已过时的列表 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

已过时的 API

+

目录

+
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/help-doc.html b/trunk/target/apidocs/help-doc.html new file mode 100644 index 0000000..211adca --- /dev/null +++ b/trunk/target/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + +API 帮助 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

此 API 文档的组织方式

+
此 API (应用程序编程接口) 文档包含对应于导航栏中的项目的页面, 如下所述。
+
+
+
    +
  • +

    程序包

    +

    每个程序包都有一个页面, 其中包含它的类和接口的列表及其概要。此页面可以包含六个类别:

    +
      +
    • 接口 (斜体)
    • +
    • +
    • 枚举
    • +
    • 异常错误
    • +
    • 错误
    • +
    • 注释类型
    • +
    +
  • +
  • +

    类/接口

    +

    每个类, 接口, 嵌套类和嵌套接口都有各自的页面。其中每个页面都由三部分 (类/接口说明, 概要表, 以及详细的成员说明) 组成:

    +
      +
    • 类继承图
    • +
    • 直接子类
    • +
    • 所有已知子接口
    • +
    • 所有已知实现类
    • +
    • 类/接口声明
    • +
    • 类/接口说明
    • +
    +
      +
    • 嵌套类概要
    • +
    • 字段概要
    • +
    • 构造器概要
    • +
    • 方法概要
    • +
    +
      +
    • 字段详细资料
    • +
    • 构造器详细资料
    • +
    • 方法详细资料
    • +
    +

    每个概要条目都包含该项目的详细说明的第一句。概要条目按字母顺序排列, 而详细说明则按其在源代码中出现的顺序排列。这样保持了程序员所建立的逻辑分组。

    +
  • +
  • +

    注释类型

    +

    每个注释类型都有各自的页面, 其中包含以下部分:

    +
      +
    • 注释类型声明
    • +
    • 注释类型说明
    • +
    • 必需元素概要
    • +
    • 可选元素概要
    • +
    • 元素详细资料
    • +
    +
  • +
  • +

    枚举

    +

    每个枚举都有各自的页面, 其中包含以下部分:

    +
      +
    • 枚举声明
    • +
    • 枚举说明
    • +
    • 枚举常量概要
    • +
    • 枚举常量详细资料
    • +
    +
  • +
  • +

    使用

    +

    每个已文档化的程序包, 类和接口都有各自的“使用”页面。此页面介绍了使用给定类或程序包的任何部分的程序包, 类, 方法, 构造器和字段。对于给定的类或接口 A, 其“使用”页面包含 A 的子类, 声明为 A 的字段, 返回 A 的方法, 以及带有类型为 A 的参数的方法和构造器。访问此页面的方法是: 首先转至程序包, 类或接口, 然后单击导航栏中的 "使用" 链接。

    +
  • +
  • +

    树 (类分层结构)

    +

    对于所有程序包, 有一个 类分层结构 页面, 以及每个程序包的分层结构。每个分层结构页面都包含类的列表和接口的列表。从 java.lang.Object 开始, 按继承结构对类进行排列。接口不从 java.lang.Object 继承。

    +
      +
    • 查看“概览”页面时, 单击 "树" 将显示所有程序包的分层结构。
    • +
    • 查看特定程序包, 类或接口页面时, 单击 "树" 将仅显示该程序包的分层结构。
    • +
    +
  • +
  • +

    已过时的 API

    +

    已过时的 API 页面列出了所有已过时的 API。一般由于进行了改进并且通常提供了替代的 API, 所以建议不要使用已过时的 API。在将来的实现过程中, 可能会删除已过时的 API。

    +
  • +
  • +

    索引

    +

    索引 包含按字母顺序排列的所有类, 接口, 构造器, 方法和字段的列表。

    +
  • +
  • +

    上一个/下一个

    +

    这些链接使您可以转至下一个或上一个类, 接口, 程序包或相关页面。

    +
  • +
  • +

    框架/无框架

    +

    这些链接用于显示和隐藏 HTML 框架。所有页面均具有有框架和无框架两种显示方式。

    +
  • +
  • +

    所有类

    +

    所有类链接显示所有类和接口 (除了非静态嵌套类型)。

    +
  • +
  • +

    序列化表格

    +

    每个可序列化或可外部化的类都有其序列化字段和方法的说明。此信息对重新实现者有用, 而对使用 API 的开发者则没有什么用处。尽管导航栏中没有链接, 但您可以通过下列方式获取此信息: 转至任何序列化类, 然后单击类说明的 "另请参阅" 部分中的 "序列化表格"。

    +
  • +
  • +

    常量字段值

    +

    常量字段值页面列出了静态最终字段及其值。

    +
  • +
+此帮助文件适用于使用标准 doclet 生成的 API 文档。
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/index-all.html b/trunk/target/apidocs/index-all.html new file mode 100644 index 0000000..aa614b8 --- /dev/null +++ b/trunk/target/apidocs/index-all.html @@ -0,0 +1,460 @@ + + + + + + +索引 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
A C D E F G H I L M N O R S T  + + +

A

+
+
add(int) - 类 中的方法com.googlecode.ipv6.IPv6Address
+
+
Addition.
+
+
allocate() - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the first available subnet from the pool.
+
+
allocate(IPv6Network) - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
+
Allocate the given subnet from the pool.
+
+
asAddress() - 类 中的方法com.googlecode.ipv6.IPv6NetworkMask
+
 
+
asPrefixLength() - 类 中的方法com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

C

+
+
com.googlecode.ipv6 - 程序包 com.googlecode.ipv6
+
 
+
compareTo(IPv6Address) - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
compareTo(IPv6AddressRange) - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
+
The natural order of IPv6AddressRanges orders them on increasing first addresses, and on increasing last + address if the first address would be equal.
+
+
contains(IPv6Address) - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6AddressRange) - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
contains(IPv6Address) - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
contains(IPv6AddressRange) - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
countOccurrences(String, char) - 类 中的静态方法com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
+ + + +

D

+
+
deAllocate(IPv6Network) - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
+
Give a network back to the pool (de-allocate).
+
+
+ + + +

E

+
+
equals(Object) - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
equals(Object) - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
equals(Object) - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
equals(Object) - 类 中的方法com.googlecode.ipv6.IPv6Network
+
 
+
equals(Object) - 类 中的方法com.googlecode.ipv6.IPv6NetworkMask
+
 
+
extend(IPv6Address) - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
+
Extend the range just enough at its head or tail such that the given address is included.
+
+
+ + + +

F

+
+
freeNetworks() - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
fromAddress(IPv6Address) - 类 中的静态方法com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from an IPv6 address.
+
+
fromAddressAndMask(IPv6Address, IPv6NetworkMask) - 类 中的静态方法com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from an IPv6Address and an IPv6NetworkMask
+
+
fromBigInteger(BigInteger) - 类 中的静态方法com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a (positive) BigInteger.
+
+
fromByteArray(byte[]) - 类 中的静态方法com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a byte array.
+
+
fromFirstAndLast(IPv6Address, IPv6Address) - 类 中的静态方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
fromInetAddress(InetAddress) - 类 中的静态方法com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from a java.net.Inet6Address.
+
+
fromLongs(long, long) - 类 中的静态方法com.googlecode.ipv6.IPv6Address
+
+
Construct an IPv6Address from two longs representing the 64 highest and 64 lowest bits.
+
+
fromPrefixLength(int) - 类 中的静态方法com.googlecode.ipv6.IPv6NetworkMask
+
+
Construct an IPv6 network mask from a prefix length.
+
+
fromRangeAndSubnet(IPv6AddressRange, IPv6NetworkMask) - 类 中的静态方法com.googlecode.ipv6.IPv6AddressPool
+
+
Create a pool of the given range (boundaries inclusive) which is completely free.
+
+
fromString(String) - 类 中的静态方法com.googlecode.ipv6.IPv6Address
+
+
Create an IPv6 address from its String representation.
+
+
fromString(String) - 类 中的静态方法com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from its String representation.
+
+
fromTwoAddresses(IPv6Address, IPv6Address) - 类 中的静态方法com.googlecode.ipv6.IPv6Network
+
+
Create an IPv6 network from the two addresses within the network.
+
+
+ + + +

G

+
+
generateZeroes(int) - 类 中的静态方法com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
getFirst() - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
getFirst() - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
getHighBits() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
getLast() - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLast() - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
getLastAllocated() - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
getLowBits() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
getNetmask() - 类 中的方法com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

H

+
+
hashCode() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
hashCode() - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
hashCode() - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
hashCode() - 类 中的方法com.googlecode.ipv6.IPv6Network
+
 
+
hashCode() - 类 中的方法com.googlecode.ipv6.IPv6NetworkMask
+
 
+
+ + + +

I

+
+
IPv6Address - com.googlecode.ipv6中的类
+
+
Immutable representation of an IPv6 address.
+
+
IPv6AddressHelpers - com.googlecode.ipv6中的类
+
+
Helper methods used by IPv6Address.
+
+
IPv6AddressHelpers() - 类 的构造器com.googlecode.ipv6.IPv6AddressHelpers
+
 
+
IPv6AddressPool - com.googlecode.ipv6中的类
+
+
Immutable representation of an IPv6 address pool.
+
+
IPv6AddressRange - com.googlecode.ipv6中的类
+
+
Immutable representation of a continuous range of IPv6 addresses (bounds included).
+
+
IPv6Network - com.googlecode.ipv6中的类
+
+
Immutable representation of an IPv6 network based on an address and a prefix length.
+
+
IPv6NetworkHelpers - com.googlecode.ipv6中的类
+
+
Helper methods used by IPv6Network.
+
+
IPv6NetworkHelpers() - 类 的构造器com.googlecode.ipv6.IPv6NetworkHelpers
+
 
+
IPv6NetworkMask - com.googlecode.ipv6中的类
+
+
Immutable representation of an IPv6 network mask.
+
+
isExhausted() - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
isFree(IPv6Network) - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
isIPv4Mapped() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
+
Returns true if the address is an IPv4-mapped IPv6 address.
+
+
isLinkLocal() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
isMulticast() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
isSiteLocal() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
iterator() - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

L

+
+
LINK_LOCAL_NETWORK - 类 中的静态变量com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

M

+
+
maskWithNetworkMask(IPv6NetworkMask) - 类 中的方法com.googlecode.ipv6.IPv6Address
+
+
Mask the address with the given network mask.
+
+
MAX - 类 中的静态变量com.googlecode.ipv6.IPv6Address
+
 
+
maximumAddressWithNetworkMask(IPv6NetworkMask) - 类 中的方法com.googlecode.ipv6.IPv6Address
+
+
Calculate the maximum address with the given network mask.
+
+
MULTICAST_NETWORK - 类 中的静态变量com.googlecode.ipv6.IPv6Network
+
 
+
+ + + +

N

+
+
numberOfLeadingOnes() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
numberOfLeadingZeroes() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingOnes() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
numberOfTrailingZeroes() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
+ + + +

O

+
+
overlaps(IPv6AddressRange) - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
overlaps(IPv6AddressRange) - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
+ + + +

R

+
+
remove(IPv6Address) - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
+
Remove an address from the range, resulting in one, none or two new ranges.
+
+
remove(IPv6Network) - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
+
Remove a network from the range, resulting in one, none or two new ranges.
+
+
+ + + +

S

+
+
setBit(int) - 类 中的方法com.googlecode.ipv6.IPv6Address
+
+
Set a bit in the address.
+
+
SITE_LOCAL_NETWORK - 类 中的静态变量com.googlecode.ipv6.IPv6Network
+
 
+
size() - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
split(IPv6NetworkMask) - 类 中的方法com.googlecode.ipv6.IPv6Network
+
+
Split a network in smaller subnets of a given size.
+
+
subtract(int) - 类 中的方法com.googlecode.ipv6.IPv6Address
+
+
Subtraction.
+
+
+ + + +

T

+
+
toBigInteger() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
toByteArray() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
toInetAddress() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
 
+
toLongString() - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
toLongString() - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
toLongString() - 类 中的方法com.googlecode.ipv6.IPv6Network
+
 
+
toString() - 类 中的方法com.googlecode.ipv6.IPv6Address
+
+
Returns a string representation of the IPv6 address.
+
+
toString() - 类 中的方法com.googlecode.ipv6.IPv6AddressPool
+
 
+
toString() - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
 
+
toString() - 类 中的方法com.googlecode.ipv6.IPv6Network
+
 
+
toString() - 类 中的方法com.googlecode.ipv6.IPv6NetworkMask
+
 
+
toSubnets() - 类 中的方法com.googlecode.ipv6.IPv6AddressRange
+
+
Deaggregate a range of IPv6 addresses (which is not necessarily aligned with a single IPv6 network) into a minimal set of non + overlapping consecutive subnets.
+
+
+A C D E F G H I L M N O R S T 
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/index.html b/trunk/target/apidocs/index.html new file mode 100644 index 0000000..0117fe6 --- /dev/null +++ b/trunk/target/apidocs/index.html @@ -0,0 +1,65 @@ + + + + + + +Java IPv6 Library 0.16-SNAPSHOT API + + + + + + +<noscript> +<div>您的浏览器已禁用 JavaScript。</div> +</noscript> +<h2>框架预警</h2> +<p>请使用框架功能查看此文档。如果看到此消息, 则表明您使用的是不支持框架的 Web 客户机。链接到<a href="com/googlecode/ipv6/package-summary.html">非框架版本</a>。</p> + + + diff --git a/trunk/target/apidocs/overview-tree.html b/trunk/target/apidocs/overview-tree.html new file mode 100644 index 0000000..4158e5f --- /dev/null +++ b/trunk/target/apidocs/overview-tree.html @@ -0,0 +1,137 @@ + + + + + + +类分层结构 (Java IPv6 Library 0.16-SNAPSHOT API) + + + + + + + +
+ + + + + +
+ + +
+

所有程序包的分层结构

+程序包分层结构: + +
+
+

类分层结构

+ +
+ +
+ + + + + +
+ + +

Copyright © 2013. All Rights Reserved.

+ + diff --git a/trunk/target/apidocs/package-list b/trunk/target/apidocs/package-list new file mode 100644 index 0000000..30c4618 --- /dev/null +++ b/trunk/target/apidocs/package-list @@ -0,0 +1 @@ +com.googlecode.ipv6 diff --git a/trunk/target/apidocs/resources/background.gif b/trunk/target/apidocs/resources/background.gif new file mode 100644 index 0000000000000000000000000000000000000000..f471940fde2f39ef8943a6af9569bcf986b1579b GIT binary patch literal 2313 zcmV+k3HJ6!Nk%w1VKM-40OkMy00030|NlK(aXwsfKV5S}VtGJbbVOr%L0@%CZH88Q zl{{NzcR^uxNo<2iYk@pjY)*5FJz8x~bc{)B zfk z+1T6M-s9WdW8dcJ-wO*3@9+W*5AY543-j^$^!EPz_4eHZ2#>)41`h@dc!2OAgN6$a zCS2I?;lqgx6IR4nkpTe;1RN0f=zxMq2O=q`94V5d$&e>Unta)^<;;^G3>e7yp=ZvW z6DIW3xpSvaogXF?_4%`@(V;s}NR^5J!3hrtJV@1QRV&r5S*L!zYE|rss${iFkg&!? zTN5V#)~=bmMorwgZsEpdOE)iExo+FO-8;8Kga{=HbSQCnF=E6W3?o*|ID%uwi5**> zJXy127Y9m+=HQ|PhXWi+xNwoWv}n_%Pq%(e+H~mGqhq5kv4Mo|-n~g|7!F*xZ{xv< zCpXS~dGg^IGK?4@J-T%b(XnUHFul6n<@2&4)zzyO2) z3Q8`i0+UKY*`$}e9mmp;tg*))`|PsK1|hAo%u0K$vDwm4gaSkm0j{`26k#qAKmbuhxZ#cquDR>B zD{s8+&TH-uNg$C#68QG}1HMBHfrP&L@@w$F_!itRzXdCN@V|LDAu%3!IDtq1#1UV7 z#1RxvT=B(DWbCoU5l=ia$Pp`Hgb_?Mp@hmtxZDI2N-)v#$}PXVvdm1d>@v(v`0TUJ zF)Pu89(q`zv=w^nVTIF3@3BYIPA}c`(@ZCAwbNBEt@PDUKe5CTR8aB66IE1!w%Amt zy+jpcn~k>GZpVFg+H6x{_uOksvBlq0OyT$6TyQZ37k(cOxZr|JEx1sGm<(M9gH z-~PMqyn|tT=))UN`|-FFFUA#KToK0fUOaz=7}Z~KeHhVC&%O27cTfHQ^WBU8z4p&T zp#>D|V}XShTD;Hx745Iz{`>K-Z$A|7!*Boo{mY;G21vjH8t{M!OrQc6$iN0V@PQDF zpadsK!3tXNf*8!81~qnXWuHZ)kytd=_y+ADWvw31ouV;CdZ#ya*(l7-A-C-Y^+iit8O zBy3*`Ls$|5Hn4m_^I^|C7{m7EFn|5vTk;|oywIgCc9Bb*=L+Y$)M>9GC<|HGs@6NB zHLY%03!dDf=eDRt2O6lVSFRcsuWZEwU?=z$CZ0W?#VJfdN>HG(l%oKpyiftJc|Y)xkjSJYCrQal-0PC~()T9xwF!Jf zVi1UA#3BBbh(i8r5&v#Pz!cF41KjbCc?4u2@@Q~oKLirt2TM30;y6b+zyX2`Yl9u; z`0$3;v0-YUp&7NdPT#q`cZlbij$jvbRk6R>8g*>}*b9E+WDwmpHAAxYzyT aU_pX{M6b8i>#Dq3onfZy}_nli%!Q$ZV%e&!tN2 zX3B0NWXQ443Eo1rUP86rLU>O>oTp%wt3Z{Tz&P*)Iraq^_@X;RtUFY!JxH|4U!>kw zxXwqo&R3Y=EsXaR!ng@y+y$%L1P3FZ4@N!j3m5MW74HcC->_JFuvlxLXiI=-OQ2|@ zpGc#>2-aN)<1RE9^`bB0`65VSK2>5m>CHs^YZCC)NX*NfbeT1%)Cxpu2_(6cCbLvjLY`hf1%*q}QO*%V4SfOu5Nqg~`-+(-76= za<`RA&(qDB^S!nIS^od5|Nk$KPXD8(qSB!f`M*{E?A^&yOW$08V^iNPK!%UNJ-@xmz>`pG2_%4I3QWk4UdtwP!GH$C%mo2K|$Ap=_)Y!#O($1@ohsUtR1k%wI*) z4*X&g==oWh`j{uP=HFm;Ye>0>UbDdtSp^~MaQ!L9I#)Ga?q}{@T#|qec*FkMLDenm zj^sCgk!^O^3o|vG!~2$$$7`C#4Ry zdQ!tui+J1*HyavK+4{`r+zvYHj9IsRt~@uEBOreWS8~2rXAR3!|7aTdr+x4|>@$Az z)b1t$gSB~6USxpfLmy^|_J_eNt*PI=ScO1SVH895N#`ef%IOh&o-2GIjK1s-JzkyZ z@r7O%hChz}kMHCM@Wqi^R-9t&%Fh^#9dVB0%ej@$=OjXA%XZdzCXf}c>SW26_z-Te z5b{}XWg&rELM=N*%aimp)k04t2c+`WAS>ZFIPWKvtyOI))HzpRA!T!b{tv?4NzF1v zNlP%#{&p@lFFEKvcroMAsI)mq?&`!e%l+-y&j9ZqhN}oG&dB=Pw09r+Q%m0cMujS# zs$a7!9VH`CC7k{!bV(J`rm%Jpj6&nLtWhPcy$onn$8G#ZdD9hxO<9k67Ya>K_7W~3 z&KYf14fq<{qHA7u6;>AOcomhdg?ianjr9uINt}*7w?g%z9{Q`(qRo@hDwSpGmxz&h&>%G%T(URL~=c>C{>y$K?+wLFp zy*M1@FTUKYV>8DeDIAIKM+!T5c-k&C4?Y~y^E zQCIc-=9~DiPtfVZB=_c3`qH3h|NXd^BcOQG`funSe)i5!NoA_r{b6PwzSDIXG+!(F z9CqJgo&~#7^VZHWj{u23q+NDCHn}GeWDC*(SW%{f4WMtP3l2jsO7*M)EX)#NLlsNnU4q@#jn0r#rsWsf^ngE0&ambG1f;Rj zfOk#_>1|25Z%?iI{0Yv8)DQfk>m1td?~}m0N%^k^u%EuUCc#ItmlY|epQ3YLWehYw zRU0qpPb#X&WU*UOU8et(s8x~WyYWYsgJCF+;U6@*nICY8)dk}IG+(#_Bz8zURd3HZ6qPE68U1%S{wL0 z;K{PDw2iRFIGG?(UiE9kT9?siuv4O{ z`dX2-eiXU3N)H2nT4V=AO^~J}sw+gr{&~qx%$$wlMv_JCWAMfcjYl}*Cfcf!adOY8 z8oLmJ{%49e+nLiVo#H9}wRk?UCzDz^>9TDxreVHzl~R*)?YU>Uu;J2eQ27O5`&X^8 z`94{)YWJQa#l0Fbz0N6B>j&8J;<%VuG6OYM9&QIdtueWjI3X;*dEtGiF@1AcvN4U> zG5SXIEXxB>)!mtQOztJLyeF78S*kLiU-!>PtQ_s~OMl~&y(hVVe$A5 zwo}E-DJ6${QP75?LsQ}Wl@MXwXMT4d>|?rD!g?jE>J^N*y;X}5FLe%d0_ zZ>eIBK6l@jkfw{p_YiDP;MS{jww{%j#?rk2z1J!HqE;Vd!TrCl_7UPef8;edI}wD6 zT&12Bxj&q}d4%$GHq+$~UYtWv`wI9k`89oKkCEK_E;-+O)(rhThjOM|kXDn{!W1Lo z`_?yQv=lp=-w()R<=0&c5%RWHY_fw@qb}uwFuPAGkl~@Kis}eE%MY@~6ZyWcF+llM zGyK`)(vn1F%%z=W7-Y=1$`w0Mv+-|#d};%JjCmw)Y1hOxwA|{}P%6LS4X`jQCGh`mR@=hGrr|cXa^Ipj;Mh)6mTqd1s_HmP0IxXT!w7YhoIHT>Hm#!;c@|L9OjV zsTlHE{Z;HWeM9^tPm-`|&nnl$%DRtNG1~?npUvgKPwKlaccEe4q!7YU3zykJnu6Sr z()LMXs_)^~u-ds7+wMff)RAJF?2?1H`_wDnt%MssYeB5;q~ojgVm6OHA6B>FG2erv z8&`|6<`=!EPKR^8Qlp5MiKwfxy4D`mN> ze$RKh_6*YJd4y0nnUZvwN%iY&^9xk@cM|5g#pZkc#N*(PH?^w&?ilTDMXFcd0`5!E zvgHS`=Lc|~1aO=L@L~eE*aP{90lc7qXY7GOs)3JH14T{(`K1D%tpvUT1-?F^1d4_S zJ#7yXkP3Q37bJlRQfv=mV-J3B8O*m5B%L3uW)S>|Jwy`|s6iK`sv0Z-3NcU(0knrG z5ChFXA@A9PUSdLI+(VU!!J1Mbw!~0VP^jZci2X|Nx0BF!24ObrAr>b=QtlyN4TAhn z!mQncJm~^m4MIafVLt_ewDUtO+e5w*!`(6A&H^F7i9s4t5&uBpNvh$nlTZjqTM5krNRRQ zqP)VR!|9@H>7qN_!+-)&_9s!^;gOvy5s~iEB&qP8{77&2NJMzZcsnJgSt_bYDzYU% zxQ#uuk3D*e7_*d5^?HW(^(WxICGf-mcmM((VStzIz%zFsm0;ZI3h=5OciJ#a%7I(IeGbFv+PP^?^sKBPrRBl<+qK^o%3fi=L9`la>-l4~p|hzAl~W zf=%(|NHgF7r5dJD+Cf08q-c(m;Epsldaz4cqHzTHT>)4xEe(cE0i~tf{Y0xs_1~Kv z+BYQ-TpEOch13;5YC9nHYEXhSv{ew=LV~nQL%UBQEgaDL2m?9u~v zEQmOvM=aB)Z$+eE38rs%AZR_)4>@2raqwH#Fji#xoLc&PS_TU^W8W(M0GqLdO~1yF z{sfHZ_sC#FX58(}d>RSkKZCz8%D7{cC3Z$Zh@52{31&V*W-@s~Z<8~aBeNcNW?e&O zsR(7fHOf}B&fsRqdZ(WK1e~s*o^uD6{YX9QJvqyWAqQXt*E>r$V94YK=X@8+{1cg> z*_i`a%alCJvbD~lCg&Q1Gk=|BzY)sejf9EHJ{s7lu4?ExCWR3jgTiET;exy{sW!Mg zuj*_YOf0@ScN~X0$7V6&KpL172rf|rA8?K<2+GelXw)NUk#@b4aT5MO%1ip4*ym}B-JI__S1R?CK z<4eW~bH;@H@tR55x}&JNSw_NvEPk)6E>XDt7*)4sgWuw+_vNZzmaS(tsi(57zcjA9 z@~XcHtzYq~IX|z*Md9mh>W~`sk3<^s7;EmyH4wcTdAo5NkUA2ofeG69{Gx7#i_*lt zQ7;N@xEo#nNRj&SbDHNnP0w#OE0{DZ$~7ySG%IN~zwd5Vu4&dnH>*OMb>&*VL^tbA zG;7y1t9dsYU$p3pw0x6mwGe6fjBYWsZ8e3q8f~-~cefgHxBangajI$kv(c*W-DZGp zbM$UgnP{_MYPXYX|6$u^deIhE(-xuGX2RVXqS+o~(iSV%;ZW1=Zqkut(r&xak^pT> zsp*I@X|-eOd^gb+sM(%3(E$|c47Y91mTU99Xe;4vFOTl5gmwVB+fvc3n2pwK?~Xd# zwrY{?CUj@~Msr?wXU0WKv2A$hq z`$V^gNq4(<*C=;4e4}$*uIC$5&uUHkM08J~N$>VV*VpdmLCuc!?!J9=-)VH;fo9)| zNN4m#^Kb9|`RF!^ZAT-z=bC8$do8~Tjc^o-aQjyc2(TW*d50E1#NW0pKb^~tf&OUlS+W}>0!m@!~1 z&TdSLhm`0u99c-z=oxYL8IFaGCDoFwFUP!1iJ%xF1UC4hhv*VR2451Pc0+kQGC)39C5 za81oV=$+xzZNYhn=RB-CTZ>Bevj)A3mi9|OS(dcy=N#Zm=Dza|z4Jd<=3IQ2CB>FiwH7{4Ej#+oa>M67 z!56)Km&2xJ|H7B;%~rJDuJ{rbZQiaX*e^$DEt~T$#h9(y#jg6>uX?boq!N}Q;EQth zYo1rjc15dETPw~*Ymu=lreoE9g^wb)ZcRe1yp1(Eo(rmqUYZXOU$BC_| zX{{&qE?E06wXm#v#cpKwE)jaydSaI`TkCCClr_lKMzPkyFT!R%VRn&sZSrchKx&4e~pJQcfViQxxl=T=7}#gYz7Pvoh`T#Jbab%2A2m zxh?A<`}A?8_GumBEcL;$x%gQb@PZ(If%ZE~D?ax#Km4a~+GV~!;Bb~qxxh@HHc|H6 zr%$^c9Dw~UQFWJv+81rCXS1vqqLfQ~-BtO63xCArGVA4T-}xPXYGHqB5h^+n5%$24 z(BROpi13J@*qFfR$oRMHel`=(zy zovs-UKHD3VkJ?hVeq!aA+8Fh4+NIlFhcC~UrR{4I#}K*u&z%68+P1*=q0B1r*2MY> z!9gYs*vlTO5v#8S>c#3goFmp>3iVKdU)NkjNV(s7tO4Wq?2M}o5Cj-*7;S=fEshOA zR*4$dm{ROvUamG%xL_tSW6}U$Nl=@91T;nC11o-iIVyVrfkd) zTCp;^tOy|_kuOFV$Nn=$AQJO9;&sZ&eDs^!r*m;Hw!)vpO1vcfj2EV{dJ?7ap0tq6 z$SwUVM*Vt+MS_`;bas-svPV|3POQi8G~?f^KOx4hg1He+Wd*s3Hl1{TfJS-+zv6vc zPoKiwr?7wECbub(IdB)9f_!kmUjBR*KY_z4E8_QA9xSr#G&@i5y^H`jB^I{|akh>W z%Cn3luOVY|8P>u>e^~#{$kmgX&-q>k{#pFbm2({(rtG<%nb0UCQ0%{Cy`F&~7}*we z@Of>ND_)V&XwN_+n~KjVorUQWZ*B6cld7ymQl{;rwlHl34K#}2YWxE+4CX@P&u6AfCda`&ZT1MOY69e-L@gNcAvwx8%1Z7lB4zc=_Cpt~&s ze%?;){1DB(PSK!^za967qF?lIjB~&06}Lf`cgh2qUiI^|$-VCTNE=hp&Ij}^A9&|* zQQrSqo3gn#_=z9j(y6f@T|OkJYv(fjwpz}$*U$|nLH2F zPNMuTS4g8 z*^hOlRh6~Mk}58;d477R>F^~aLO$dOXmhA*6zwIaHK()t2zKjo?j^NOJbh_=+71xg zO{Mgp7x?Z-1MKzoQ<+V2g#|e}|JawOPJZBL{o~PYdtWDX?jl##!Aiq|w>)vGJLipp zBK1xGhcvgSsQ;rn>+`>UmxlID{<~}7{y>SO^cyktN^Fsz!Z|B4?p*RKQG*8}SYBt{ zuFO{vJ?jgL{gUzYsnv(io}c0vlCp#*1vE?}KL^UZ&VF^TK+D;40CxX%j);%dCt;Z{ zAeMXC9JPWvKGwsCxx4w2iv_wNGG8l16AVI93rmc^c1>r(P||YE zpXa+=-&k995hfykL^J5S&vJF^ljR&`FE#ppNMM3%Omc!F)Mn{{&Ip#)JegbEJxud2 zn`wDVB~DMii5|H%m~51YeU1juNG3!+&?*uC#q@)z8q~`4yEL5I8}PtyA1IZ=52P$x zX)KhZt z7czUXBsy-8d`GVQ`90`wIh(Xt7v5j7h0t&ET~2M!Tb~4rN-xtK@8@mB*c(6QTwOS- z%9445_WY|cfm4?$nX$72&{~^mu}an^x^Da%=UU6YI;ur3+9L6I>raW5!=-Nzy(F2Z zwZlg7aM3NN5b{K|FB>s4R}|&Lr32_Ys{wwkECxo|rV@;5aHB25iUs7(6@dDpjN{Y%?C~UGp>*Q}K?)KKk64 zAn;@-dER}QG0L${jQ1cR75eM3-~ZTltTQ8%sm9x4Y`ve@ekMuvpA#Rh51@s6;6^&Q z!&M7^b%cea7FlZkPV9}@!bPBBfB&~XvGlE2T7V?IpM~OBmuK;OSt{~N`rL5c_I^de z9n*=@p|l;d`b_YIn8Aem1t7pp0=2-MCTIcJHlY z6x+mNLgi{JpwP)y(yzAFL2A#>bI&EwZE`PGvd*FQ!rx~6bUN&+Ij3)L;=595L#G;m8*^e?ap1`J5w7-q)*iUT_W9w8 z&xS-`i++HpWzY-a-)CWd0(pLW$A85P{Dy9r-=uPekNpN^yA}pJ7yWTZ>3iw4d6+IK zF%1XXkGcJm{0*vhSG5R1ySW;jctk9O==1-Mk?=Bl<{HE1p_@tx1s^+GoczYxj#B=i=kwQvEPrOt`<4W*pJw zbNjEqpr7B|Llc%m{V*QssV)im;pb00LUob=yFaU4`P_}ywU zt*QZl-bUsmh@L&zQaX4uHL&7YD(BOb9hH;;y;O-b-_O$4EFi1vCrMlz`dN|u?}HNO^aFQV{UZg_yy%nf>IXpulip!cR8|vNu7P*; zQye@}Qmj%(TB6`5E=c~w=LITF266XJ6X5xA7!OM1SE=~N*o3EP5Qqx!W<_+EMSLGo zqkC18AQ=0AK9=hgGQtrTovYc5^?Z^RLX?hlO-j&e1MXTTbfm>MS^=}!p>C>icUKdZ zBcNOb(6IJ!kq*e7N8Fx!!kPyn+2B2^2hd00+W^PUA&+S63jFE)bP5Tv+L5l~n(pu? zbeO|+K{{?pEow3?j0+dGVu)a6(0r{1Uj7{3 zxSsZ|BdMk>1-S}-;+`pk{Q5>H=tLRx+YqeenaSRsEX@gtPzz>j1A9g!C9kGtspY(- z%YL>NkVDE2z@}*;Q{=&5)yS;NupAmmibGUE4qte7aY6PcnXJgw>}ad(SW;@HtNurF ziV0_yHz=;Di%Tki6DW^tjkL`t%Ktct(ay zvuAOYoCu!Pm~@P5CIjk$bp`_iv{^l*Au{fB8mJK1>Macv?GL)**8*+JNvySIH5Y7i#1;!%NT!efc z;Z0*AOM&1VpR+6wIQxBM{xf`8T1V@#e<#QL}=YRwMkWG8%1(Fgj{iX)N zup{Txko(DqJWf=#Oi?Z!nra-?C{);TP`w|4>L+EKx1&P3swX<*#_50F!lD_$nQyuK??!UwA-{y)^QmMxoK1xIJ~uML{u;5!Z5tQyEL>;KaUd!_9FP zl2$QOI6V1`QdF|8gkdZsSpUqCjSBu(1H)r*vL#PEy)@Px>5TIk7_9o#Bj zzD&<1_k(ejk%qO6ak=GMmG5b7LTAA^KKq-Ey#z8(2wy2;Ot^oZI(MG@)~iY$RAnJt zu`ioyvR?Vws_tuK9hDqmel+)bP0kyxJV{7t=&3{b(@Hs1fs$9n45aq)IKknZa2H*7 z^P-ZDyOMdMj&-9{(-?dqo5I3Gy=K$!L%q>3^0N~o^2i0^_@^2nQv>S4B&=5_8^a^V zaY!NjyA5QgO&r#^CJcp&=!))MZ*CC&hvLEzWU*!IO=aYo{_yG+53H$XOAIQWnG`uD zLuuwTY6e8N^m5^AHQa}Y5Z#SdbEY;+x{oW?g;ie4CNYomRyQd2mv^L}T!>a5<*wTh>@>Qtwp~nejn`~DcZJI+QC-xU zoxz=5z0k%1;jBrGI%Th~FQElrAPr?E-Fv9|o09dPk=?>f)jFKL8PK|;w(cVDq>YWP zEfL7RGBv|<>f4IccND3wCi*V8`>#a$FPZu&a{V`W`me+Kuf_CJ)%IV%?5ByL^#3Q{ z&uBM5|34IKI>0_Tz{5OngXe#6w*N6;;5PH%9n%56%RaWA{wJ4%515Apdj`a62bp<> zM12OuV+QZ^55ATkViO(UWgg}%9C}kb^r~=BiDyWIXZWM&kb>Q?dd$#W`4KU|2#4qh zz;sZ>ZqS5h#Kdk$&1c9AHmDUdtmHE)CqH0RIAZEE;t(^+RXF+*FlJyk;?6Vn{&MsO zZ0HwY)b4Va!F1#s^N5$-s9(&mPa*Lu4>4SxXm~l|3?PR2jB1J!Q|(4#0i$lFME^-r zA~Q(2O+PHOdcVN((R8zqi>%+yx4PA5u&+jI zZ?)Fm8m-+`n!Bnrx0PvZE7!Q)Z+NTE@K(R!nO40sZF(n~bq_b_9H`UYU#q>pPJ3UC z_UeU>J7qcy%%`ks9)BNcS^GDOn z?oKkjHNoWO1e2?M#vd12e^_AscAnLnc~-CISiYWX`D%{k^H~<37unpMYJYdSv=Om2vbAM@`Qp{{SI=yP zj6WN*eEt0G$9EPX6FU%)-ho>hWTW!yzXBIo73<0umM-=@eG&niY^` zlG(|vuCl_x(X^Fob@=i{8+M5vWf7Bz=#aHGTNA;fZQyfbfueI8Z^639n`(DI%w^-^ zl`=@!u)r~Xf920-xd$Ab+S&PJY%K0H8a_J8uN3^_!K1_NV$*e#*Y*6|)XpiW=9H`*`Xx7W%v@7{XDma1?v0a%(K6rI&1!a YpWXKgmku8Vj|K)Vje`mzEKCg608Q#dYybcN literal 0 HcmV?d00001 diff --git a/trunk/target/apidocs/stylesheet.css b/trunk/target/apidocs/stylesheet.css new file mode 100644 index 0000000..0aeaa97 --- /dev/null +++ b/trunk/target/apidocs/stylesheet.css @@ -0,0 +1,474 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ +body { + background-color:#ffffff; + color:#353833; + font-family:Arial, Helvetica, sans-serif; + font-size:76%; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4c6b87; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4c6b87; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-size:1.3em; +} +h1 { + font-size:1.8em; +} +h2 { + font-size:1.5em; +} +h3 { + font-size:1.4em; +} +h4 { + font-size:1.3em; +} +h5 { + font-size:1.2em; +} +h6 { + font-size:1.1em; +} +ul { + list-style-type:disc; +} +code, tt { + font-size:1.2em; +} +dt code { + font-size:1.2em; +} +table tr td dt code { + font-size:1.2em; + vertical-align:top; +} +sup { + font-size:.6em; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:.8em; + z-index:200; + margin-top:-7px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + background-image:url(resources/titlebar.gif); + background-position:left top; + background-repeat:no-repeat; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:1em; + margin:0; +} +.topNav { + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.bottomNav { + margin-top:10px; + background-image:url(resources/background.gif); + background-repeat:repeat-x; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; +} +.subNav { + background-color:#dee3e9; + border-bottom:1px solid #9eadc0; + float:left; + width:100%; + overflow:hidden; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding:3px 6px; +} +ul.subNavList li{ + list-style:none; + float:left; + font-size:90%; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; +} +.navBarCell1Rev { + background-image:url(resources/tab.gif); + background-color:#a88834; + color:#FFFFFF; + margin: auto 5px; + border:1px solid #c9aa44; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader h1 { + font-size:1.3em; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 25px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:1.2em; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + margin:0 0 6px -8px; + padding:2px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:1.0em; +} +.indexContainer h2 { + font-size:1.1em; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:1.1em; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:10px 0 10px 20px; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:25px; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #9eadc0; + background-color:#f9f9f9; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:1px solid #9eadc0; + border-top:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; + border-bottom:1px solid #9eadc0; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.contentContainer table, .classUseContainer table, .constantValuesContainer table { + border-bottom:1px solid #9eadc0; + width:100%; +} +.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { + width:100%; +} +.contentContainer .description table, .contentContainer .details table { + border-bottom:none; +} +.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ + vertical-align:top; + padding-right:20px; +} +.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, +.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, +.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, +.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { + padding-right:3px; +} +.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#FFFFFF; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + margin:0px; +} +caption a:link, caption a:hover, caption a:active, caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { + white-space:nowrap; + padding-top:8px; + padding-left:8px; + display:block; + float:left; + background-image:url(resources/titlebar.gif); + height:18px; +} +.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { + width:10px; + background-image:url(resources/titlebar_end.gif); + background-repeat:no-repeat; + background-position:top right; + position:relative; + float:left; +} +ul.blockList ul.blockList li.blockList table { + margin:0 0 12px 0px; + width:100%; +} +.tableSubHeadingColor { + background-color: #EEEEFF; +} +.altColor { + background-color:#eeeeef; +} +.rowColor { + background-color:#ffffff; +} +.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { + text-align:left; + padding:3px 3px 3px 7px; +} +th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { + background:#dee3e9; + border-top:1px solid #9eadc0; + border-bottom:1px solid #9eadc0; + text-align:left; + padding:3px 3px 3px 7px; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +td.colFirst, th.colFirst { + border-left:1px solid #9eadc0; + white-space:nowrap; +} +td.colLast, th.colLast { + border-right:1px solid #9eadc0; +} +td.colOne, th.colOne { + border-right:1px solid #9eadc0; + border-left:1px solid #9eadc0; +} +table.overviewSummary { + padding:0px; + margin-left:0px; +} +table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, +table.overviewSummary td.colOne, table.overviewSummary th.colOne { + width:25%; + vertical-align:middle; +} +table.packageSummary td.colFirst, table.overviewSummary th.colFirst { + width:25%; + vertical-align:middle; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:.9em; +} +.block { + display:block; + margin:3px 0 0 0; +} +.strong { + font-weight:bold; +} diff --git a/trunk/target/classes/LICENSE b/trunk/target/classes/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/trunk/target/classes/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/trunk/target/classes/NOTICE b/trunk/target/classes/NOTICE new file mode 100644 index 0000000..a4605c4 --- /dev/null +++ b/trunk/target/classes/NOTICE @@ -0,0 +1,2 @@ + Java IPv6 + Copyright 2013 Jan Van Besien \ No newline at end of file diff --git a/trunk/target/classes/com/googlecode/ipv6/BitSetHelpers.class b/trunk/target/classes/com/googlecode/ipv6/BitSetHelpers.class new file mode 100644 index 0000000000000000000000000000000000000000..d4fe3ab5d9f7509f40b235c811a5d95671cf0770 GIT binary patch literal 838 zcmah{&2AD=7(JJ{l%G6 z1IJyIvL@krFO*LtyNV9u>6qwwyfnvaD*r&nY;QDEejt#ociMkfXmQb*Sl^Fqt0kwy%bpK1(yA6*BUQ`CVSr0x7B?oTm||3R<^Clq>#k2K>AN&DV#?x zg*qAn<^L|}w1I1lhONE9p|Z)&2sz4nyU|C9_m~JT(cqUOK{51Nw1PI;Jb`#mCxR7z zm%?NoXXvNq1z1IzQ5_ij{Vhgyc5ZUoWlq|L$qj7cYRIG+GOXdkf=P`P1u_9@ cxJV`j-zpIW))kqJ!}tzEWE138VjMyF7gKwj=>Px# literal 0 HcmV?d00001 diff --git a/trunk/target/classes/com/googlecode/ipv6/IPv6Address.class b/trunk/target/classes/com/googlecode/ipv6/IPv6Address.class new file mode 100644 index 0000000000000000000000000000000000000000..2f79cace2056e3a920032b76262272139677dc50 GIT binary patch literal 11074 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 N7<16u^p1MI`#=2_=DYv^ literal 0 HcmV?d00001 diff --git a/trunk/target/classes/com/googlecode/ipv6/IPv6AddressHelpers.class b/trunk/target/classes/com/googlecode/ipv6/IPv6AddressHelpers.class new file mode 100644 index 0000000000000000000000000000000000000000..09dd471043941fc6516f01edb284c3b0e617eccb GIT binary patch literal 4835 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 literal 0 HcmV?d00001 diff --git a/trunk/target/classes/com/googlecode/ipv6/IPv6AddressPool$1$1.class b/trunk/target/classes/com/googlecode/ipv6/IPv6AddressPool$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b729c30baf392400b251cfcccdd74847ae456bb3 GIT binary patch literal 1660 zcma)6TTc@~6#j;8S-PxJD|o*kRB7vFsTaI}7sMhpfF@Op#+P9`X&0BBW_ODG75xLg z_@If3(L~?GPW8dY)NH*TiYR(O;nNKLs_8}fvWc4vV6dw}Ai_DH zN0EpaCVD~1mo?6e7kG+zl?pw^6jvCGIikiewCDw5xxKzB!iRj-ro#DZ{Rs;_mY$-r9x?;?42Gzd@IUdLhH-`i!Aimm9>6 zu!#IH1+DQ7?)W@tIQLiAgsaFaQ}Y@DSM87-tA9HrD{bZZPSP$J&iwO0+qrKLu2qxm z&=vEZuFvovojj+BP$4UU>&wUs8cRYoW!=Ut%-R^n0UHN#%EoQ%wUNVK6LU81;Dn7) zJybAn<1Q8$M&lF3^p<6AojKh5;|WD>7u*x829znxgw1 z-;GIz@g6`K2EC}V+2rkrszC|3?~{fVHEZHO>iYdQTHJN%ZssQ^DeFQ{H)*;T<&G4( zgjiD{31qssLcJfNZxO>D^wC4I0J2%F7W!JH>34-+nkyCOFIad0J{+HON84|Qf4E5|22Ht)_=E)YU zZ@-e{U{I08L2v2kn9I_fAO@w#9{Ui8sS8%$+!$2YSDxwtI(>O!cpaP%8ewyVd{Rmn88%oSi D7RiHo literal 0 HcmV?d00001 diff --git a/trunk/target/classes/com/googlecode/ipv6/IPv6AddressPool$1.class b/trunk/target/classes/com/googlecode/ipv6/IPv6AddressPool$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c0200df732389d06136cdc4655ec810da3aba2b3 GIT binary patch literal 976 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 PpWzUn0TS88C;$B~LLMZZ literal 0 HcmV?d00001 diff --git a/trunk/target/classes/com/googlecode/ipv6/IPv6AddressRange$1.class b/trunk/target/classes/com/googlecode/ipv6/IPv6AddressRange$1.class new file mode 100644 index 0000000000000000000000000000000000000000..230a8f4a67e2e4428bd1366ccbfb0bae480a1f21 GIT binary patch literal 239 zcma)%!4APd5QhJul#=Mh-9a2}IP@+;;vj@4sO_XGYgfAT;T$}GhZ57Plle0<`IA52 zWZs|W3&0%x5MhXj5FOp4)VwYX6Na08l`OKXWbY5D&3SrBtCTQUS#6vzY`*3D*<~Sm zgo$=nl{=Rk)-GdJ+^R(V0>(1}2>p$8uCD0 VO%cQeXvq%Hmf4k#Btx}}J72$fJYxU= literal 0 HcmV?d00001 diff --git a/trunk/target/classes/com/googlecode/ipv6/IPv6AddressRange$IPv6AddressRangeAsSubnetsIterator.class b/trunk/target/classes/com/googlecode/ipv6/IPv6AddressRange$IPv6AddressRangeAsSubnetsIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..f133c34d577c68fda01318407f4e726deb9c26da GIT binary patch literal 2714 zcma)8-*XdH6#j00ZL=&il-4NaM}PoLilh{+*49EPMWSg7O#usvY?4d5ZL*v0Zfbqf z2mcA3!Pma{pffgQWJcbd@&E8|a2WNR&BkVmY4gy%d+(m}o$q|-+>`$P_piSJ7)4D* z9FtLce5m40OsTkr>%5)j4>wfI;3hw2Roucy{C1m7vi$b3icgSZ<2int=d%R`cT^n3 zl!CiGSX6Ngc}7}Na8JQ~1rG#51>KPXXL3cWnkidWxgv{JNoI`N##knMXJc%-RI;Vx zOpvK5H{JbA=cW6lWv`KG#9c9*#2#(cWQThojxEwT_s1lHw+qa$)RjFh!MG7 z*DEw128LemVZNK^I)(Imc20NJ1Y%EZt9r+lPmRr-G|TP^U8Vg9v^i7DpRDSeMzvn` z6MbN~D{TfeyE;qQX4jR1t@7ji0rrAihGEP6^0&gLR0M8ft zl@IX50AewoK(vq02@NE&I!n75+68DGNDpr#klsNso&E)Z=Ll^h{IlnNj-DzT2?bH1 zB1wCV+{p>&F+{82N#FziiI4}lo^BxW9i9Xy2`@a@fWm77J>TOZzs0^DEImiG0ks+L zPy^Zzh-@MHtq@!P{J}KBNAZnk^&E${afFYKG|(GrAV%!AaOee&F7Kf4C4cydhy=l8 z(?l1d4~pm~!f_0W;}{bsFfLBvnmCI^aULa+LPcEil1Y$X6pzSn*h_2OPpg8ke|Cvb zdl7y`aGCI5NWLO$GNsw=XPu**S&=xirauyp6M6K)<6IK!;b(~a9>9r zS0?$ms^cuK=~%@(>h)bUdr!yvs4K{tnqAkhu0zK)4L2rmQ-^^KwfTXDO%1m+Yzb&~ zF9@U;3d}Za|De|P{kAJ@za?uHqk6DsA8DZp%ZumM&L56FAijE&KDkR_8>L7j0fD zS4O2$7SY_EOD;|h{63FKQo3-C(T}XYRdeZOZD;S1w8OfF+X4`{Kc=0d@<&dUmg_2E z>X4O99WD!uN6s*T$)?lxtgshQxA|Ya@k%dr+}cS!)<$Wnuaj4A`n|xGw;fgY!i%-I ztc)=*gYyOom{zj|4R;KD2-CpJIA`D^m>NDd(7;^-Ma&x5#*RQSvNRI3?KgY&{+25b zcmcK!ZP^JO-xF9Exc;fv?R7eS5X#n0N3|0H!^mB>UeQS!t=I|tzSEN3Vj!(n(f8ah zik5Bj>L`8p3|vA<;QEMb7FXoO1D}{DkRPavdxFXe-VQAB z!+Dk$Zwe{?*kM3EuX>N)x zog?rJllTR%a%M1`L3j-pIkHhPn-DgLRC_a|$;MQ!(N;*w81E=vO?NN&7hSH}YE^u)k3rX^;Os+usQy34YP95X4N)nqB zokXOEPNK(D`3=f1Ck!=?iXlt+XC6NvOlJqKW|Lrgh{YuM7E`4eldCQsLk#K?n;1tI sV?=TaRp_@^aFsHLw{baQs6}~~upEsmc!Q&Al05&AU+1jC5&4OK0Iwb0wEzGB literal 0 HcmV?d00001 diff --git a/trunk/target/classes/com/googlecode/ipv6/IPv6AddressRange.class b/trunk/target/classes/com/googlecode/ipv6/IPv6AddressRange.class new file mode 100644 index 0000000000000000000000000000000000000000..520975c6a0675613cceeb5e0894fccab54b35987 GIT binary patch literal 5909 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 Jvy}HB^dDzc_D=u+ literal 0 HcmV?d00001 diff --git a/trunk/target/classes/com/googlecode/ipv6/IPv6NetworkHelpers.class b/trunk/target/classes/com/googlecode/ipv6/IPv6NetworkHelpers.class new file mode 100644 index 0000000000000000000000000000000000000000..25c3f5b70de938b31b57ffe0ad98f2939f04db6c GIT binary patch literal 1122 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 Id=2LR0LQlxDF6Tf literal 0 HcmV?d00001 diff --git a/trunk/target/java-ipv6-0.16-SNAPSHOT-sources.jar b/trunk/target/java-ipv6-0.16-SNAPSHOT-sources.jar new file mode 100644 index 0000000000000000000000000000000000000000..d8b14c355e5695fd1ffeaa94c7b7f2c7543263b4 GIT binary patch literal 23816 zcmagF18`U|8;@+cb60UB}6YJFV3j=UodDu-#?i8LQjh2zt?{M zPW1mBCMP5>B`&7&i$PBOUT$hqR)(Ho9zlklW@c)(QJHCpb?4BLW_pTx-ld{Rd2F06 zno)9ECN!-0#Ix8qa4GE^X9zF-&XF6dm?EX9#6Ot_lZ?Wwh~|YNrTFO9ksFiT%s8bO zlUNpUOsblSUd>1n@s?0|2!DUt0kGXPc3o&Hu9g|BFESFNB$$otd?Xk)5&0 z{{j3TTm6sE{cm6kdsmMCwE`Nz|IdJ4^SX}%PynD70sx@+|5+hy;jCifENNnGZ{q00 zU}@-TX!FZZVVw#2Ge_T{lC3;A4wHh}0=fw_8~RtZC~TPA`%X#f(qJ>|xwvvYbk^lMq(b&fjDO&oxK%axLSs)W(}sSNriw4#Tn-i;6F=^iP;wPs~WaH zT^5DLHnm4#5S2S-G(=>Yo|LN)4C1nZ13Aq`w6nRXdSqHZ>B?K-Q?stk#;_fS?hERbr2W2@>HIJ=MhxAXCV*%|neX0kvxJk=zT!LvJ zUgc|76K{IAG}*BYpjbS>Ed*vr3Th@)Dk~`FfH+52?%MQ*sjHhn-t?9#;FMlRmNNC0 zE=S({87w4GqAi>{&TUfFc$YD^aLsZV zIX4jWF#^x6G6b9fKYEAOHvO@7>(w#(O-PVifSaUano6ApE3E=Tyi0>97aSy9`R@Qx zi>Z=Dd)Q37+?;Z8@3Ec15hN)_6km~aMcL2vH7zWr01qHX zp;%xlymU{&Tr8Qk)%M=e)AcHyI=q?0efxN7J}nx)SVfyO<@b5TO-|b+(;T)Vtty!w z)YFLOYkwh;?3m`%e@PKEai})yJj|iQD!Z*I1^@QR`3K1|(B-=Fuf`3dJ*kyWkA(`b z-H)w9Fb-7?0}Z&HDyDSp^<^%%qc%d0)`@Q~&HZb-v*w*DQ;a&1ciko)Y2auMs;)JM zI7&(+X-GhVsE_@x^5l`v=Nq{>o(^q~`6C7A7p!ncVfE!y9)kAIEgTmE`M?+1C&=}y zKMS9Y&itg_1q*G@YU_kg;A^xOtoYIVEv;ay!JUWBqGVO;YB2B3F>2t=$4|C?+eWU$ zF3*cc96gw>?v0`Qbr^5(tRo4KqbMZghJl z>?5!TP*Y!70dcg+>RPYgFT4A?C3p`|xMfn#*|Mg&*RG#(;(EcEUui#hi|LA(k$+5k zaFs9@q9qKYWuX2nJut?J+Ku&GAoeS!hD%Jlc-P${7Lwt&Y|bT(bV-O8tD|rjkQ$-7 zfyPM>K_P!wOk?1NF=CO&oTP%^VN-Q(q1;Ab=($9O zB?RMsSY#1{6P!lwmZBVRQBTsMkwq&<)n0JmLKrpB;+q8GkT)KrlrU?Erm*P-!52;l z_QN!U4~UI{G1#hJ2n%`f^6nhRjzJfk&L$XR&O5N=`?huQd-pVgNt07k3P7|5^g_RE z2q2gRrY+*gWuw}~A z4(zUZpw8;dvJi@YNo7DA>Zou-?!WT8hhls-s z5hjs10TpEe0Eby5m2TpN9J=oB5ub`oaJL|{EJetBnT`(jMk`kaC(mi`fP7%29CJCo zexImPUZELkXJ+vkusz(bcyV}c9~K#OHF@_#thMaHmA$V5LqB9#sVRZbiQER;7Gs+H zVo6o-pduKvzvt@9)`1#th>SzL`iVfXV2w!OW=Nn8&Cho_lSue}I741Y@bM9y;~-b; zj?f!bk|skjM8nvT8Bg~g#wsE7lrI=$yR9ga_v8Mgd?s{o1?F<*fbb-eh3IC!YJcKH znsSiW*G#G?0aTovSx{OdpT$3R0`CX7&cF@86o}u7sdr8-JTe3Jy?ON`AhRy(08&I^ z%+x8!2vuHe4W=LoGLbzUEMXBlIvuJN6cLL+Gc?7*5l_A^${+9&u%_ZKdLoonmA8?$ zoceH^jH#7wR|iFZw{w&uuRJ9EU>~kLstuJd+;)6IerQjsyh)9tGSSFJ!K|x!YR!>y zY1xRx2b*04F2Mpfho258wtqWN1wzmWP7zmceI*8dEe_V^J_gRaFI*4&`Ce?SMS53w z^3pB5{*BrE)VZnGTiY|Q4bE9ERk>~VS~lE&g%@=_v;ZwU(Qumu4i5vNfP7BG$N%tW z8#5pQfg1F5pn?2%ds$jd8H)wF(^^U*%}R#!25|!H3fYTJ`rQO^(8f~|1*2XZS7d?f zmu!JlMwM|;Vb~1tge={8WSCXWPEDE`lhDWM8;OQuETwek zQ#Xw%U{TgPWV3)mEY2Ut*b%tF`wNMW83;6vN0Y~#`ORbTEe;cSkG5uF(vc?#z#(2s zCRHwGOeMh3^cCI5Y1>C)e1PA-Qg$%6Zd<{3Zo2kR43pleKDETu5>t74LuO%u1l=ZT-aihGa7n+Br<% zwQAL7Xnd0xu~D1rH5nAl*Hvs|rS?k;TB)%>j44tiN3Kk7&(c!)g*ErL0h$a9c8c*5 zHEO+16A%XK-1>-NN4$v=%UBo$nhLF&Vdp3Iu&_=YRka*6`-ET$s|_ZV@uwOf z$wWgO-7%hYp7Fb0R3zbE;po&494 zNG)C0U)#j}_cG(QR!RM=ph(fcQr7wb=!om@xphBrSE<j?Uw>3kH85T!Ctxsi@l}V!DdXz{rRVuo(OJzJ|C_ zSBD@Hn4@F*;E?Ub)eXOgll<3BvQ}j3FO*=_Z8eMYaHMz?N9;ByZ6VppM0x1PrN0b4 zDj)b8OE zF3sY8)CL~826tgKCmmcctA_;DwyEKu5tCkaNe_%aHUMKXw%Z!`W0>)bNBHR%;^Yg+}@p#OrE79D|*B&8qAGC zb4PT-O%e&lFbHbDKwxDslV*oQB88FbnIh`}ubO0-#%rJ>%*g$l`+Q+>fmtyQeb>>3 ziVc`ZlBlHiG}aO{I#)q)EwmZd8sOmHLJb%cxSP7BS+CQ;RIR~%GWD;Tzt+X$YWA%@ z?xY0TA`c=1nd*Nn-BrswwVmfVvGwwLyqw*>B?`60Ix4M)77cVjc%-UIt% zOh_r3+^G(jO{PB`?4Bd{w?ueDTI%6_d);EbF;BeAO`OErK)!t$?T`R{oFMO1ALYb! z0(`7sc7=+FMjNqAWu`<{bF%T!@)RC8(*_hJ!F_$+>`0@^is*o_37m}n38YnR=2$K) zC-ho+4vygvJoy+7Az~VT*0@MupEqr{bQxfP~ z#RO_-OT9wO&b;A!ub00(VYe8!9l3hRHBOGsqFsYv$h%8bKF3n-!?Xpy(QE)2sPKCS z{|Le5?nYfadW$=g&P!?N(K9pT=tgKP!S=LaKUl1_JwKS#ydLWia>L}eH(o(%|B903 zYXDICbMMM^bad2Z^)@)a(9P|{ye=Pwy+sCYG%3b$107+w+`!0KrL(ke7$08Cqe3Xc zs`vnGsebEgg)=!@5sXnfFR06Ze#8Rza0jPWlF9sdOK_)6OTqV5%>Jji%T=p$>^QwF z`t2{%2pj#hzlSL;G?AOa0ijPo^1_=byeTtRNES}T2B+zuS7H0v?re(@k^s%cWDw^?`YI&0|8_>Z zmpr0~3fVE@vNe+)u!0%xctpTOf|Xdgr_ueb1Eb_5p#}>@*aojj4$JP*tjg5)BW*Rr z2;b)@Lz%@C_opEDj@E#wNLA0JUpc9tIwngi_# z1I5qvi6N(*j^^;=z{u+>lLGPHJ|8XB>xyK9SP|wZl3P#2!Np{!3#$5`k>UD7=OjCE z9~6YT)P)K$p07AMI<^>A4W5}*hMUG-eWZ@4<83Os+KWlFi6vaL)~qWj`UGgLN;g6HWNa9hKVN2J3e zxzz?%ZNB?9F4e0-{1de87rMwwxAFrQA1!IK*%-%9(4rFk*+`(K@0xy>g@GE}b zjV6VICQxw;V#Iz+-9`&2Awfrr_Jytsy)Zl9q~(d*3Ihk-bI1L&gkHrHq`UjcC>;NO=4*nGD9k~VN|?+-u?Zy^+rC<;52*#^(`76mjnY?v!EZYJxj`< zE@nzq@ug79&*_AY8zaM+#p}I<^Sy3IB)G9%qzo_7SB1*_lRv$%$iI1ygoSsnFkPy@f{jO| zI8`F$siD5$$$<~yN)&gRySh=;6?(0D?oi3o-Q2V*HpQ2D5h8^z%T)z6+JP;8SwqwR zEUGlxeS1YEZT@{L{%r4=4QU8&)S2OE$C}71?pFhjKZ?*3Y2?sXgTQ}q4Aj zjlcnK6bj+xRe^3V7QC+b`#FzXzil8l4Hf+jO3QJ;ZvrTjz_Z0|b7Dtaljcka2zVwRq-;*g~ z59|CFkO06N1^__&e@~|T@0rJH4I3w13DmEd+7rcOT|x-%A_MNHSUz)rFj-mO6bdAF=7M_K>A-9mTPkSG{!dX?Azs;L-cq%p zZaRbhDw3^r;B!yuc!{|Wo|A_xrik`*s(&Xxls7xEdw6>Ba|I~o3>SIh^Oy5(dLh(}Zw?4G zrg)QD~7(7ep4gBJ-t321~cg<>rGn;$DE{KGL4 zZy`9R+VTlHs|xfg#rVDrA>ujre@(Crmdi37y>2!xsznM)nd}H$#0&@TYVs*YY@RP} z!UR*-?6po|4~X!3#b$+W8Ho281eh|Q*%*y`SiC%4t^JUyx^%cX6wnZ|TC$aV*79H` z&Q<<^N$F=Z5?xIJ)C#wLtu!zfRria=p`T9EAIMtZCti!5#UTa9W3haMeSp(1UWvJ7 zfisT&)H6gj>1E3b=qo0I&D?_*vpi}o&9pHV8-gH*p})>uSb-~JD5)jXbD(Kfcx(7sGKVhhj^q24-#k5;eE_pjA4NIEmCy6HrFI68 z8<5EuFsN>J)1?w%btKI|Ks!h`m}CN$j0uN+w4n+M+fycY)r1Ik#1HAo5J{JxhE~JI z*9taa-exg~@`4;0{cv^r#>+O})BLAgx-mNlUcP1bTKR112jc@T5d>EG6Ts9wRHh0o zNXL?f(CtNu$?eZK;PX%HgEuCm`t?*6^y9!6W=d#?|Ee_EgmUs855IMd^)z7=+HnYX zwhYG}qkQE)4$gTfQpuQW7J)3X3?-JGN`VLG)qvV>+#zov@i)iB7)ASW`J^(ovM1 z>A`rmsP!R0Na)~HeRp98qmU9`m#r&nDyqx(N zn!>f2Q&M4?y?X#z@4VG`u^&`IrKnW>j*%=%z;9QTfnlaT{KDFYN{_EyxJH}42KE>= zp-wzy&O@IhdmS{1YHD#aH~<-!31~&U5`4X4Vn54z0HG5B%h>4xuD9 z5jE5qwBQj3iNs9`*5j}6KlG(DXB$OuX(1TZKVn3ab}tF=a53HaJHDRJ?<02=4px{j z*CA82w#q)&?QY)=9DJgE2>X+vq%Se)_Eo)!zF|7j+-b||U8XTnbX&Tp2?&bgdyI0V zBk;3j;#c#zYczyEH-QG>aTd%v>ob|1GZt#bHP@y!#G|O<)bVR#PtleWi=zTcq_W*= z9(y$qA-dfmvg+oYMosIVSF_{KFRY6``j@4mMUZn``iZqbJzlmVL^t*frH!T8ZGhiM zGKU@YJIDL-SH#;UeY*s@Ml=a#4A$h_Pi_}tUXwhU-$X{8DRzo;#95N8CFj6;6LW%& z`W6v(2zFj+bSn_;=*`7V9)sN26E(h?H2FseRwXa#(WGwfju{Nwp5@l0F=F?#Bg?a!*gONxUcsn~~jwr};srzL(~ z2JezPyPFD#mpyvEg3q`8n@$}Ygj?U6HfYCQClwxd=U=xG-s%azYL9Zs!cN}s99`B1!wI#8X!t;DbxbqrzXPYnsD1Pp<3s!V@@4 zo|@B)H+l0MSlJJ;Y?sey`-bBZRAym;)4prx%HLl-^2f?-4z<&`)RdRse6VKTCcIjc zk21JRN@)oZr72rAc6$!oM}AkLrW!KU9uX9ZS0e*&)qZXx=%#I9>D?sjer$!&pl8Hg zLAK?g9gB`UqK>UU>%_ba`X{NXeat^0{(I0&wK`W{LIePEMF9Y+|9j9>w6nAR&syCd z{B_55j;Bq1kn?=n;)eZ!hDm2f0#0zW(2ODmn9@m^&GZ*5YvT zD#{qt^x+!HESi+8FS)*~WCC*uW>r5FBx0qAupS;Nw|2OJZ6+9+K))%SGNrb*T;^-1n*Nhkv^QiBF6@qKsT996sP8@iIH`Qan8%3+U< zx9*K=QK(WkVabsWH7R$ur{kG!W?0ufAO(*lv10Pvl;oey6Ve9mo-zsS$m}vDf|fbf z(6mwwRMcH)@ZnoY>0=SYarPWonMFm=6w_@~jTYp5={TqXPHrHQ2;f_pI&q1SgdY6u zTI?EDs*vY}?qZ^r&%J@!3y-vf^Z+_qK?_5#Lyt4a?2oBfO zK8EBoZPP~b6I-!qUf7KkgI*^^MZAa-5j-u_lP(&a8*4h@%!=pGXug zhCwtOL|Bj{p~T-heez_DfwK_5Sfu4Y=;F zlIgm}y~7SXc>PoDY1qjpe->VD!20Wo+8C8a3P~qPI!l6E(!P>FGNsZ3JR5(fsN?G) zHem$Rk0XmiOxuz3Dp%tAFVjJ>IFJi7u&L4>Koyt{BM`S)8bFuXNcIaZ(fHF~6jGC% zf&P|eN6Rx|62GyG(CF*2gqt^=olj_lSXEIF(*jc`30eu;id&c!_XiDx(>P90^`HrS zK_6}caZuhE?msUli5#dDQyW7DEmE}qK}*;Js%N|eKr;?zcT-r1$%7=73no7L!$X~z zd_?+E7J8phO{O9V-`D^L7>bf87f<|6Mgq|`ey77?jh>$$o!m_Qy^CFGntv|oS){5E z@oV?2^(D5*&mFm;dC|-b3r7+>moDSBEx(1>R@5aQW<8i3Lsip%+E$qGJ>rh4BY(pl z#=k&*J2%P1aZ&3pRys#m*u*v3z==Pd$X7>=p)O{wF^YU*HP zhyiM+uTi$1ZcSW_UvZaYobs?hOUUF+{)xWNtv3}TfqrE>XPhkD;TIIBCf68zBm_rK z99%uWqtWf*>-xP}#hwoHSeuq!!`{}|0h|y3x6C6sc8vLGB@$#bmo2BpUtu~9M%G&K5kig{eE3Pl}*^ZlZAC{=7LeOmZz}tsEy7ao&Pkx1x(CM3| zF5B;$LVBl)96&Dq_(#u7a zM1MH0{_T!BsZ~wr)F~(iM%lwcY<2p*uFvSQ21fbp@h`;>`Se;qOX`G6BY_Im-CHXq zTblO{0S0Ld@h+&+pNH{hV}+7?4X`bg%Z)K0OmtW=%W?v9sA@}ng$S@~=@_exW8=R` z!$(4*IbnZtC0Om(PmuXLxffBeT<)60WP^DbL2DlVX4lJ27hep5fT<6O5`ziC)X>OasY>{13N8! ziv{w^us?tl-ZqsBHAdNP0o^(9U7F^@wZ2ZL1Z9-BF-n&^Wn0?+LyevFx-Z)t(4-ooge!hY5{WZ4v%uY;Yfg1RZ_(cK2aF*i_+W5 z_6Q#+BV~I`^aJqGLp~z5;K0|oIOTe>kDDOwYYqvO<-|=%wP;LX)K0JaPW?GD)_F;# zP}jQD(UpjtRo#jHL4D~whCAA_u&ud<3B2Bf%o1B$eC#5Hbi+ksgTQf?pZk`_(VF19?C_{TxnlLyoJT@7Wv07?QD!k?R)!!z5Kr#G@S z&bRFS2?<|8Z-8Y7!k(!=E~qPObT$R%{0O9vJM2WhAtJ(>$9}hIm}BQsL;A!lc}R%i zA&|ACo@5mFeC+q%zGMT+XAZg1aCW%!Y|Jbg29{F5PG_=+u9igf@(gfbN-RoejTi_v z`LxP>E>BZ!%n2WuOUcJjh|!D=I!ttdsGxT{m7yp)9{V%~pJB4ws0%gdEs}f|-1#!a zw~KeD7LCO6X^Ks&npMgh3YB$*Hud=X1ShRgxzWNvp27C-E>i7BW5d#u%+=Ij}bVVTKH`7 zVBJz!IB;0tTuEEv;?XqR>4IS_%+#J!s*P>ALAI?A_t|yN?^r4Az2V4B9U)lXv|H?} zytmRy(L9TN)fEP(^$}+IZ0araq*Ed;3e#o_pyD5z{)i8WyjP8*{Hh5&JJ)%6N4NPb zvvWBbrjAhya>HHs=l&ViV~*!eQkDpW`*4|&kY6-XTNWh>MNXSS!|)+CRQxb-ziRyuHB>Zr9wG`__YV_6QesO6Vy?;zCvax{}Z!I ztM*W6^HmFOt(@y&2v4P2cg2eRZX|J;&j<~w2&X_f^zD2%A@n)1oF@>Q&FE9z46~jo z>sLXG4~zep{ArQih3$|+wbl1)jnwcqhHz{=mK5Ez9J8SA0i-b}n4Px=9`475bRURU3x)GGnO&0xJUH>!({5OLzaa@Dmi*qEX@7`;W3B`lve7gz4e<75<%j z5JRDDEE|IdviOf^d{@1FP_p?H2SByd`Q(da>l!gOY&KCNmos;Ft4#DFG7fIWy9jm1 z>W6+87j!okq5LkPI4%}yV-54zg2Tyh=r@BUkS<49fAz$ies_L zo)D{s0k1l-3Ok>{?yXZO6T;a#<;&#n$IElfPJ2c?j~mE!5L<`fGRlkSqUj#*`!m3~ z4qm;da`i)65qc>@LzmjU3}Lp&8nr(f!PG-T@g+jCiBOu2u2U`c&try(9x9n*Tu1!; zui$wzk|xE!C>@|xQ01KgwJX;EO$2>6Nbd}`9r4c>;iNNBwaFqt( zT~^lQp3tqe$=JENgnnYL(tpTfyYwU3J^;ScxC#ZEcAPR@8j0!fSWzCe_bVmo9hgdn zjF28>?HB+G|4kxv&RLdOVf*IAp*c77eydYXl62osi8}Z3KNgW;An}A|KP9M3rM^Q<1+XD@T8-hEWgH zT;MctEPYwDK3AruZ|4;(AHrYy6hH6CS)_=BO$9y&Cp?cc0*|2qW!}+(;}<*p~E*Q^xRSLR`7j0J%K&tv0% z7+^?i4*U%uhrgEZ?R^iK8wUOCXTzBy7hJA0wa{Z&{hjv0?k6JC2*RBlSMe^#e#GEvpfH#dp8NAk zB=z2(N8SyD6U#WHSI~uV*(VVlt=L7etD$&x1H`CG zhq08t*X_E`ZhJbba+cAwkUHFLR0oijkZK7GoMfHBnvEOxPABw*FY`SJRY?pGWc<{| zp&5&TS{d#EM(>|TusV4!z~QTO&(~;SWeWm6Vyepd{r2t~l!)qt^%O|0Cr;Qp<}sRMV=2Iic)OpWnpuFxSub|T{$a6OP6^HX`S#A1Nm z#l}7kkOa|2^piKlzu}IE!p>m_u2ib0C;+eMzpuEBLt{~E;->xn=Q@iE1G~uvc1KlJ zm;ps`f%j!1b(;#De0UaYPS`VokIji6NqiaR0v2w<-DXxdcq!q6u9AH0Zzw18CNY~u z)i9t}{~nTwU|Yy{Y*2$fMh5a*sGYyoq*C*FK#r(nTJ}uE@1K3;iW)o9#u21|4?;KJSYNz zL7Eu*+P{*WAgDG?hB`hRztDNW;c7OIjlHIi*STi_LALFj15(OKVgB{r(_D8h_j}os zx9aWad|h>~LL@myw&G{m0e}bdr)Ajrr}Gd5w~yYL+CZdN8D=C^x*rX3Wm=pGWR|f% zWu5_ZM_qEPW7$VB{rwH}v9TaK34=;Nyc?z0n9H)bfidqQb0wrx4zZBkwKLCWdE&>= zMGTK~E)nJBrkeRnt9ws<_eu0*_ItYxZbp8C#EBvKsu(cfO&}4BmN@_viV1n@;n%@6 zB3>6t-UEtpCQjf>MfP3djagyhK)+LpgJG;Z06ZjBXC%diy9s!Q&aeqk)HY&@AsRN< zot&;atk6@d&bosbW2b`M{>HP-W>0#=W-gKlRMgN}f+L|^$tcV?y_)*7PX1wJZZV-6-BE4R@TIfW1Az{`;4|xA$ z_Mi1OQ0OhYhUgwbh~qLZ-y|31gNeGOu-v^S2jB`Jvjatm_1$Fm3#%Eh!q+R-idV5JHX2%Q$0T} zG4Z!IrtfTp2=ZdRB{7aL-R3LMj{ZV3wgqED$ytD3BR>DU;%G0zO}j2?uYDlwV<1UX zjlSsUsmQP&)<9#j88mG+8%KjA)Xx*)V0>xpo@{FJ0)#ClZvb@FXL&@-1p7fY`zKQH zgTqAQTN2L_9exI116H`{5^SN=yNiz0dD#l=38Bu@U)&g7{+-HK1x3E_i^kbEY-klk z+QSOtQ8^;`n?GqBFEq16k3&6pYAUID(PGAH=O&KQJXb`hYkL}4TeJ9yiM?@V>nZ-; zGG~=c`O#D<)<|L`{mcY^^xL?%|_X`GHIlCaL7OM2$UE#2T20$bU=y~|J2bw_KkP>Bp5T;!trd6~~OLQl9D^{SF@h1q)~_%Wnhx$}@0%UfvW2hpjsvPiIoR@hvB zt6JLS%DmhOOz&b?{1dGGtyd zmJTljnm(xuEc!%~Pop19Go$1S!wSu2jGw6JGk=@=Wh(=0*MIZ4uTYAqbnf0w?`nkf z+-CDrk9#4fk^dKQ%D-lCvZXCwY4CmT-;L$>=6oTJ-~QK37cn!Q@o=4AS;U70=cw4XDVZSBgot2LyNQ?&zAuEOcGxQq zJy*n^v@*|E5X{qSfe)1Cn}vvVMuF`XMc`K|-4S#3h-_4Q=Z=>~JEUwt-~KP5N1LwH z(R1)tfoVZSkA?@@IxK-`fJ-eHB0K zRn|-|G;XJGzl;SOE2!)d6zk|`U*Kl$BT|RG=+n(YE-m9@DCL9I#L|f)HJotj$alO# z(->hZf78GAo<;0KXV>EIN6-z4;2O_|s8{P67r3em99)|!);~Kcl0GjX9~w8oFNL?K zTd86`b-Fzdx6d~g%OAbS)1`raVE>&1zuJa}G(rOaQUw3!`4o8*XE!@XtN*0G)tcW< ze@9TivwMFJPGv@*!(9}4;P76-Ib>5aqO*jsE#~rsat-|vmQbLq(?9?2?kr7oMg?8J zOdRD%cyfJq6?nfq>9+2dX-mlTA|FT&Y5Y2+ePN8;HT(GNL+dvp`;ie3?Vfc5QFIHW zoufqzM1Z@=^;rzgZI=#;+MT)%lmNGRuh?w=f%(i5%-$KQVJV3g!zT(VgW|B`2C{9A z%na_>9S$A|hRB<*E*^8ZhZd_(hs3=CKaRt&y0f`J4qj5d;9T9bmG$h|xjADdZm3^T zhhIzSQQ0DGjky_xGI(*So`=38X$0 zCuiWTwL5?CID(Gchyc9V;5hd6&jEuEIB(n-zY|c2$b5X?R;4DeUn+6zuLEhe6CPs0 z#Z$keIrxxePZxi93<*?E$LD3EP=2LVRB^4!mKugmzR;?k6QFi_w>xd zc5nGfhC^WOJ3Xt`+d55JWl6tqeT}q_YSZ;ziA1@g*pb>h%DQBm!#?tlA}rP(Ea^%u z>N;XxGDhG28bJRMhUrcnNgRCS`7>e_kth{6K_%}lw1{rcDhJ4E#H ziiaAyeO%Ox3E5YOt@D41304hNsu8E$A(5U#VNas;_o|FNJ4x zCZ{$9%+@?e9jH$+&-|X%-3U&&ldoEA#_+M0yYlEL`|;Aw&ahklo3R33$4FQ0Q=ARy zeM=?lLTwg0opzt*Hx=oS3*67EWoc8UX6DocfuamlBXU+8K0irvYq#1d=(g8&Ydx6*ZV+sL)mWyW|QRb*Ba12z&|}!xyLLGm|I63w-l^zOoc~A zluYDMVmBFcXb5=WF0qypGaFVC2??z&7{n{&wD6aR7iuILD7=<(sA+|aGUSLu zJy9Mo0ck5+JnMP0s|HoZxP~$Vh71F9OM0bx$?!RQ%WLw8j+Zp@VjP>WXAW|k;nPwJ zxF?PEvtz3eB6Z@2iT0^OPSCywD5hCMb~^_+-I7?8dr1B;Qh1BvVA@k!athywcR}($ zXhoYt218>L-dI8|v0H{q&1&^>{hp7u?Pk~bG_s!WiD*EvZL;X0iTKYRx(kErJKYZAWF>)}G4mS}?ah30*KO$f~>iTq~tU2>>Zjx<+)a7%=e zXtnylvjf%jfObsMO&TI)ixCr>mjWtUaxENtjxH7^hbwL`O?u-_3SBvTPLu|Pt$55E z-sjl*=v|hzRu3{AT%Ueh3Inkmd#0$gsEKo{r*5hR#bO}22S+!nfQ9>+iMie;YMPamONGq zJI1#BaP1^+>K&236z8E}4o%}awt0c8-1FNJv(=`JUOfP_g_`N_o=qiK+{}K$r>=?A zk-8#Fma#H$m;?2) z9*5vu^#iRmMeD%i8(2sq-B-0yw~j9R1H!pafD6o2psX-c@{;iRlVv9FF^yxspi^Sm z5KH8&1nR;xXI}v>RDmvSl}DrCNSssoyX#{rS!qqT-mF23L_p_PWoQ265|&COL-m)J zUFMR|nX;iDOV3kcvc?&Tz9kYRBNw+~67H&Y;;&NO@4i#1ufP1)6R-yN@G8-qqn;kF zVq-C{*-waTqXpA6QsIt6sASKl=a?lgvRCJ-$cCYgFrUZNM+M|ROK?n@h2JexRmh7b z54DEeKt_06P80magm8&}Mq|HsHTD(|_f5)my5Zj+kanc-Yu&e^>mA4Whe`lz8`4AS z_>3(%IUFo3czQ1Y(zs{ym~ge!)|MH(X7I5)TLg{-QblsdcDsJG!=Q(?hbcs&8mD25 z%xZ*hu;GjpcoQrqkY-yfl)&MWdL_q5)Kf1(@ohM<=RP2y*$%gbP|FYGzmuNJ#613n zf5YoK|AyE9Pkp5SMSA}CK2jHzb@_EcWS?jCs5^gDCJx1LX|Z1jsj!PwLR|jt8>>cU zk&Wk9F-8Rue%Do(LH6avR8KlHSx%;$8;=H9GcN5cEV*d-1o*xIR{1+QerD$6Gz|9a zr0IDLX~M%6vkZE=Mg{uTDfDHHzlrKuP_0Y2T~shC*)B)2&LkodlJ5X9QeCu3e~vi85F3% z8@KcQyyc@PM(DSzM;8)nfSw^6maN4&ze$|!=v<(sOZ$HcISZh;mTiF!&I~ZP4(EQ1FK76Js<-~+)EJXmlUoM6F%eeS>SzU1@od-qID)u}qQS9hK2 z>gqmw_e#gI9-N|Iopf!`H+d6;GG_FClA^{sXms$%_m#H8F@dMU4b6jcE-JO>o5>TU zuE!W19L{y#maXmCB6<``#ps|i_gYWOhtOdvk#SmBFJ9!_EL{K2Wfs<1F8yR6-sCXVyvnRsbj{lOHX^*+1D{H~1-j)U;@ z>%ljB%>`@c%cE2H0T)Arl{H8&mb*^i0M(g@?=N74mzN<}u$@TV8c0>cneY-kgvM#m zU_0gv`~MDoQX-+9xVvHRf%o65!TvS$Rm?s9T=VbgEqaX0;sl(TR-Fe`711%VK)vl> zcZ5FtsN#f*M)GZWnJo*B@mh5*YqucbZpr`Ce20FoVa5m)-3VhYG8ijxx!jw->z;-HF8m4dU2IAzn zIM+K*@c1;6xg3nVPoyJlRtQj;8cSPC?J#RKX=X#(RV2jhoYThU=-nWO&U7OLa}c%0 zNSE_5-!Kq@@Us^Ym2i@J*U|Z`91=i!If89GuO%vyAJT$<=D<5k(^uAdh`%v&sl|5d z195pO$fzCUeSLUC4ofjOWor&g)l|h^RhXzP8h1pD&Nk%tPn=tzjyJf9Wwnr-#=ggI zd5)6bFL&-F`fLU*?v*)t0F-$EU=Ff?UXpt846&nQq)U$h&$^_1(+tQ9*p_hm2%m6S zBLkl#j%e$|0$#Y|N6V8~SIfn=FpuPnOJ<8h=}HSB@}!}2P%)p!)xxCS!sv<*kft2F z=e|acyrB8=>dhWR<)*cMB5ccnl9qdKsHS-fF%_I`)eVu;u&{Y~*4DWT( zWy0~ON!jMvmVfDOZZ)rEuKrd@QS5aziRGa+!}0a28Rd+ER+63U0fLF(IX93yGP)u@ z!567SHnUu-q(lOR*#0PL#wLBozFGuWzHe^I!-}=QJ1GYOY&Ps;P(p8z{;7E@!NO~5 zsE=CVCbtU;n+v#$UFJIToplt7%a79>Xn_ZT0Kdf-sROC-3yo?h`Pco(;^R8$tR&_t zi*Vu;#1ObE2M@0v68FHi1aWLK31PNhVe&<0ih&}BkvZce-H1|pxY%e=nQWAWRk<$u z^0+xwT-?i>H6q;4uwnc{J*(WB7tWZ2n*Dt1knp>_mOP4GsH3UXYNR&ZQHKT607Est z%CdjLbs5*phnjUOU7>bQb69rRB`JAlgNrwZ4MFcrX)dc0@`dsKmv>Y1(mRY%;xY8L zRzCGZVczV>@9V~(6UG~t1ZHQt<$=|s_0*))qRX>`vnD=4-(|x>#&E&*-`p#sO2CvQ zA!CNQf&9w4Coz)`*7a2|^naoZnJj3nf{ql4yb`T6s_@y(b-qMEl)6>!Du;-@7@Ube zx{(bwW^ix_9lKemSe8GJt6|x>eKEhebIE#H7<{x)zo^CJkgoIEosyVZ7w_FPW2{>Z zRr%UwXJs5cu|?Zp$|Rlf+*_%})l;&#xxhC{jj~E#Roh7;7utKIt)10JnPXez>g28F zM1*hpXH*+2u(N!ykPnbN&+42T5VxI=V)KCU^HZ&?s)b^WO2E8q0=*B0*64^w7= zN!MZZuCC#|(1#AV3cZ7a2^`q$RuhyJ1xsX>K*7L#nj3n&1D8ju*CR@(-_Sog(<}wJ zcwSHCm6-aJxn!vAG5PQ%ri@d+mG9ylpFEi1ay0Nch-Pwd+;q=xI)l0U*}qkF9B>FJ z|KaC*T;gqfnhReZ0y}lP9sMv3I!q|Cc^>RMJQyu^eiALR_hvrg!EQYC{il7|`BQ@I zM)Yl)+5}Y~50#4!L;=+;dKEK%T2N$YYv=t2jLvA?d0&7sy0Pt0WAW_JGLgUEWUmpa zy1FQr^pz||8UE=|Lafp0=wkyz?pD#>{SCDEAl-PL{7vX&-&HTi`+1I`ZvJ7PtoD1$ zncCWwaHl)Rj|m$9fOeP1R929Ftg7{R-oWrqBSIK(Rx#~fsAYF|bc)vwvJq9a7G5T8 zC)4Q62#sK>E2dsY1KDo-%l0zQ0MF8!6a5%f#K%!;<=B<$ufI@@rc%w&nMUOM-kZP zSip08j&kiXkw<~<&NrP7JjYBKzy_$wonb(P3#Nef)R4*QNz|ApVFg}Ym4#;sj_%2% zwq=wlu?c~gp`CzUE9v2LnyeyMC7q~2$x@wusW!xm$yc*k=c;LBVz$0RNtPd)mi0I- z)d*NsURL@wLqcbK20-dSqU~ksHNo9i6SsxeEtwvy;aTL!j!kuVMBaveeX}%L5>8L) z$`yV@;aNtY(eEWEFem^G0!f$jIeTD8CX!|3E?B4(rFI~iG7uG+W)p0DsloC|NA*~3 z*;WhvZO-(Ld9Satd|j9T~0F4AE`prziWIb|OgY=AY0cSC>#Lg?|F(tdcSCB-doU%tAFoSeeFn z9zj39*lfLOWxCQAoK3B(pZ`+IvxAF!0(-07KoKwS5*f32nnL{ z^L;A#N8+E}A&wFtRVIlgS#^a4I-8;T3U)#aL6nns^FOAZVV{(wA?FGrIEV7-?5Ckh zoE(bIOyU)2Oxu&nV>)^*%hS|;(362}w91tbJX;(AkvPEIY75rYRx5qIq`E&Hg>Xf_ zcBw1&tAI$#o(FT$b775@i(BrgK?s5lfngU|S% znd`xmLgZ<7l%~J%CJ|IByLh2BXa2k*h(}VLfd1g@s=8=7d6?0)E=CGHqXR8hnk17S^zC;!c?6C$keAW5Ju5{NE|Ibl5TB6 zG&P5;N;KsqBi1uyXlh2ZCi|pc-S&OQJ1d&Y=9L*uf-2TU zq#Gq+1lny>VgU&jNdw(#T0(a;fucz`4w%nJTTe={B=H95Ev_qO&6?-{m*wOpNtcnd zcB+NA&bfPP!|i%g4#vj&;zNCld5e3^Lbvp#MLRW&Dn5_C0>5rZKE;=MtFp_i&H?{X zPq!PPE<=@QJ}gTcJmH9PnnF7~ak0xA7Ju#~>fHw$*36y@jEvtKEwn%za3tu$SC@S( z4_4f`ETH$?Zopl6-{GW$bh_>y8!DhAj+$4ou~H%b!F9Ib@H|LA>ZGrGqIY}7no+5S zJeg2iA(2#`Iy7*oYbBBxAQY;F_-SVXkOEvr8=2C69&41(Gp}^i5`w?ln+o&WC4w+{ zBn-Ox>KmfG<;7`6)1pmytL?FPyBwZ78%&sB`Kad*IL08j--}g>!YY+>8XGDRzZf`V zWKZ#8HR|y~1Dsdff-4aYr5H}~=p^zUq2fWCS45t_McOxlaZg~UnT@z(2GIru$3gOx zMvwJ*_7RNH%tbD8BH<`uMe+Pzv7*?~f%braiNa7&9?dU}B)= zfi{=Qd0q;^tkPH0a2-}iamT`yqqkrsEwH}~;#L!~>!oU-GNW%O@pfdCnZn*Q`<(bY z-Z!&x7E@e=o4`aFUA50~#Gy!T5j!8)i-zf4N-`HM;>*$NoHD%DC!KyB$UBFSpu>$P62*ua@M4Rlv^G-sZUd>cK=Mr1oWM}EXU z4RV_Npj&||TD4hgj%77!{X_#AZh26dF3YLA6WM0e$2PQGKm6_8u$DDw9FCpgSK^7) z0HnE+g-|5@lbCaFUSv@~mV$`tP&98j9ksH^I6MQP^L&7xo zsLAnp=tq(ubC-;7nWxf+?MnHao2+B?B~z3)c--16JSqXc)G%e9$gNm#nFP!-z+D?Xut8c-~W z@Fb08^Q(RhEwe)Av9*P05ia+ENFp|$3mygo?-_oHyHy(z1Bt20;j?Zs0*F{ z1^(A0$zH1+t6T-`MjNklF|=ca1o*Q@6cRvVrp%7ljVgo(+HFX7s5?bU6_?SnUzPBE_QdtW!+!9<1p`_)j z=u~c8u5#=v>3nIp>vI(Or2u)NHLQ&uA5`ClB)4Xh7Xa#o=)7yPcSLf^ zl2HZ_eZLJBiRX&NBo8Ms3$N*y8Go>uo`yDkD0nmdP;K5YlTTy&L1g_{Wi}8ty2R>% z0y^C2)9Fdfl${hdZ?qxtC)>+v*v@K+j)YX>fw@Ks3&5K{>k<;7(dQkv&$T3#yQ z)nL39Tofd)>2pj=j;+cjH)be|7oo&vAs3IC)%_o-R0B7sfsUw zF)Mpm6REMwg_z^sN_!M3xSE5p>fp>00#jsjGAoWl2v_qG0*fA3y^P`J7V`nNm~;`H zR(#19>g+%PvaXV{TK@{qx##E2f#L`RsE8{#L_Cznq*6mcEI!_Jq2Xu5_R6N6eBq96 z&P1eGs;x;cVCikQ=)xBy>k-l;sIk%o1^g2wi?Vwz@s&9u2f!3hcNT(x@s$%^dn8@d z1&vOGR#uDgAm}&fg=1ggl7K1JP!gd2>)VYLMG^a~gRy!ds-Ty_#$YaBUdbCIfy%GX zEMt<*0$c99ni;`_{pMn4#+oOHUfsDJZZR3+v8$h>JUHFTQ4+)rOS|14;fu3Pe)f9! zy%&BRFF^IZySICO-omTB#U$oU^OeEPdX`>k0MSd+^76p%wrvOjU0X#;OrxQ!I{b_( zq%t0wq^{cl6^`_1GTP^$Dzh(_@axMR#L_muMx)kd!}1%y>+zHAHXL!|#nx-wTBEB< z|Mr&Kbg9kxqX4hg^(izWlb*d5F!|~7^@{3Tz{loReN&G*_-rSt3z5VvCI5uyj)VZu z9HHtb6j2)$7rrqMVOOltuz2+=hOWW&ccM<7U_o3;0a%@P=)M&3G8Khi_>pBSmc_Y74Pfz*Y*VMEWMp(6FP zpS3kJeb>ac;^f0c3h(J3wpqOnjzS#z0coX?k{fVxqr}~3?@U2z3tHOrzVZ)v=%+e> z27Vg+nM?(883kz6t#=p6T3+2gP?Yc!f}Mc&Cu?SH6dqR`i_{n+o!OTuQ zOzLwMmnh0Rg^ji9EbDUEto>tOM0Gi`fpTsC$n4%6%4;xzPs!fF#A{w0%Nl-3A9McL zw^Fz+&%!E0zNA(dEQzLZwzZETNLq#*=FeC%b(LB1lFabnXAa4^)OxCTL-2$e+KF;$ z%5TYncsrQ4l$4p~^XO&Npm}VVSIQ*M8I5_wEIU2gpibMiZxkm+$`3$hJrn7pjkWAF z8q`yx(JWbV4&zSgZ^@AurJuwNKET$98E-sXU+R|?9zkGFa3t%$5{v11#V>0t7+CS- ziQbdpR#drmPG^_pM7a234u+ipAky!kf^)6n`?5>HfY<^<$Ko|H2lJH!!ML4N&ID?8 zj}$~Kv{*J#_`={rp*tc7nO-F12GxayP-cBM)zk*}+?IR!!#oW#es0PB&uUda4vuo= zvxxIHiIjZF^L-8!ubr=j!a2k^K#9YA$~KX{0dH@Cn8p=w;70r*ZBmAxF2EI$h#$;Z zbZ#fkgvG2n>^>)vL}LlBkFm9;igx>GFkkdz05qR~szT0@8RX9UQ5G}Xyew_O|7WVH zx(d1|#r|q5ytCDTe7Jxnq81KzDHS3ad%D7jc7CaICFK{AE!R-mKDH_*Us7t55w4cl zj`M)yAn1Gu4nJe2{XvJ0Y}9sjE;`~nf5D%W!zHU-AV}+VZ7n^{EkrsKCXphIem30d z{*&_KrTvR*JncdT)6S8%E0i}`JOt3#ud0i#ok}5BLGMYp1m%o7j_COJKuj89TVT)+mZX4vRK}2#sTbi|2tm=KvhlqZcnbI zu704%rlfs<$;`8=sjlui#972Ppghd1@sRr=FX{lCB^04b%ihh}p7Kuji-1UgbXS~w zcm18S_O!dyC(p^{{ZP``|AJz literal 0 HcmV?d00001 diff --git a/trunk/target/java-ipv6-0.16-SNAPSHOT.jar b/trunk/target/java-ipv6-0.16-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..3c2ed7a9d305b3f3e1b62af268dba776abb3a981 GIT binary patch literal 33116 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 DqbS<) literal 0 HcmV?d00001 diff --git a/trunk/target/javadoc-bundle-options/javadoc-options-javadoc-resources.xml b/trunk/target/javadoc-bundle-options/javadoc-options-javadoc-resources.xml new file mode 100644 index 0000000..8b89c97 --- /dev/null +++ b/trunk/target/javadoc-bundle-options/javadoc-options-javadoc-resources.xml @@ -0,0 +1,10 @@ + + + + + + + + + src/main/javadoc + diff --git a/trunk/target/javadoc-bundle-options/package-list b/trunk/target/javadoc-bundle-options/package-list new file mode 100644 index 0000000..42c9b95 --- /dev/null +++ b/trunk/target/javadoc-bundle-options/package-list @@ -0,0 +1,203 @@ +java.applet +java.awt +java.awt.color +java.awt.datatransfer +java.awt.dnd +java.awt.event +java.awt.font +java.awt.geom +java.awt.im +java.awt.im.spi +java.awt.image +java.awt.image.renderable +java.awt.print +java.beans +java.beans.beancontext +java.io +java.lang +java.lang.annotation +java.lang.instrument +java.lang.management +java.lang.ref +java.lang.reflect +java.math +java.net +java.nio +java.nio.channels +java.nio.channels.spi +java.nio.charset +java.nio.charset.spi +java.rmi +java.rmi.activation +java.rmi.dgc +java.rmi.registry +java.rmi.server +java.security +java.security.acl +java.security.cert +java.security.interfaces +java.security.spec +java.sql +java.text +java.text.spi +java.util +java.util.concurrent +java.util.concurrent.atomic +java.util.concurrent.locks +java.util.jar +java.util.logging +java.util.prefs +java.util.regex +java.util.spi +java.util.zip +javax.accessibility +javax.activation +javax.activity +javax.annotation +javax.annotation.processing +javax.crypto +javax.crypto.interfaces +javax.crypto.spec +javax.imageio +javax.imageio.event +javax.imageio.metadata +javax.imageio.plugins.bmp +javax.imageio.plugins.jpeg +javax.imageio.spi +javax.imageio.stream +javax.jws +javax.jws.soap +javax.lang.model +javax.lang.model.element +javax.lang.model.type +javax.lang.model.util +javax.management +javax.management.loading +javax.management.modelmbean +javax.management.monitor +javax.management.openmbean +javax.management.relation +javax.management.remote +javax.management.remote.rmi +javax.management.timer +javax.naming +javax.naming.directory +javax.naming.event +javax.naming.ldap +javax.naming.spi +javax.net +javax.net.ssl +javax.print +javax.print.attribute +javax.print.attribute.standard +javax.print.event +javax.rmi +javax.rmi.CORBA +javax.rmi.ssl +javax.script +javax.security.auth +javax.security.auth.callback +javax.security.auth.kerberos +javax.security.auth.login +javax.security.auth.spi +javax.security.auth.x500 +javax.security.cert +javax.security.sasl +javax.sound.midi +javax.sound.midi.spi +javax.sound.sampled +javax.sound.sampled.spi +javax.sql +javax.sql.rowset +javax.sql.rowset.serial +javax.sql.rowset.spi +javax.swing +javax.swing.border +javax.swing.colorchooser +javax.swing.event +javax.swing.filechooser +javax.swing.plaf +javax.swing.plaf.basic +javax.swing.plaf.metal +javax.swing.plaf.multi +javax.swing.plaf.synth +javax.swing.table +javax.swing.text +javax.swing.text.html +javax.swing.text.html.parser +javax.swing.text.rtf +javax.swing.tree +javax.swing.undo +javax.tools +javax.transaction +javax.transaction.xa +javax.xml +javax.xml.bind +javax.xml.bind.annotation +javax.xml.bind.annotation.adapters +javax.xml.bind.attachment +javax.xml.bind.helpers +javax.xml.bind.util +javax.xml.crypto +javax.xml.crypto.dom +javax.xml.crypto.dsig +javax.xml.crypto.dsig.dom +javax.xml.crypto.dsig.keyinfo +javax.xml.crypto.dsig.spec +javax.xml.datatype +javax.xml.namespace +javax.xml.parsers +javax.xml.soap +javax.xml.stream +javax.xml.stream.events +javax.xml.stream.util +javax.xml.transform +javax.xml.transform.dom +javax.xml.transform.sax +javax.xml.transform.stax +javax.xml.transform.stream +javax.xml.validation +javax.xml.ws +javax.xml.ws.handler +javax.xml.ws.handler.soap +javax.xml.ws.http +javax.xml.ws.soap +javax.xml.ws.spi +javax.xml.ws.wsaddressing +javax.xml.xpath +org.ietf.jgss +org.omg.CORBA +org.omg.CORBA.DynAnyPackage +org.omg.CORBA.ORBPackage +org.omg.CORBA.TypeCodePackage +org.omg.CORBA.portable +org.omg.CORBA_2_3 +org.omg.CORBA_2_3.portable +org.omg.CosNaming +org.omg.CosNaming.NamingContextExtPackage +org.omg.CosNaming.NamingContextPackage +org.omg.Dynamic +org.omg.DynamicAny +org.omg.DynamicAny.DynAnyFactoryPackage +org.omg.DynamicAny.DynAnyPackage +org.omg.IOP +org.omg.IOP.CodecFactoryPackage +org.omg.IOP.CodecPackage +org.omg.Messaging +org.omg.PortableInterceptor +org.omg.PortableInterceptor.ORBInitInfoPackage +org.omg.PortableServer +org.omg.PortableServer.CurrentPackage +org.omg.PortableServer.POAManagerPackage +org.omg.PortableServer.POAPackage +org.omg.PortableServer.ServantLocatorPackage +org.omg.PortableServer.portable +org.omg.SendingContext +org.omg.stub.java.rmi +org.w3c.dom +org.w3c.dom.bootstrap +org.w3c.dom.events +org.w3c.dom.ls +org.xml.sax +org.xml.sax.ext +org.xml.sax.helpers \ No newline at end of file diff --git a/trunk/target/maven-archiver/pom.properties b/trunk/target/maven-archiver/pom.properties new file mode 100644 index 0000000..316372b --- /dev/null +++ b/trunk/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Wed Oct 30 12:53:51 CST 2013 +version=0.16-SNAPSHOT +groupId=com.googlecode.java-ipv6 +artifactId=java-ipv6 diff --git a/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressPoolTest.xml b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressPoolTest.xml new file mode 100644 index 0000000..db32c10 --- /dev/null +++ b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressPoolTest.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressRangeTest.xml b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressRangeTest.xml new file mode 100644 index 0000000..d603fdb --- /dev/null +++ b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressRangeTest.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressTest.xml b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressTest.xml new file mode 100644 index 0000000..41506d4 --- /dev/null +++ b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6AddressTest.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkHelpersTest.xml b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkHelpersTest.xml new file mode 100644 index 0000000..a1a681f --- /dev/null +++ b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkHelpersTest.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkMaskTest.xml b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkMaskTest.xml new file mode 100644 index 0000000..42de26f --- /dev/null +++ b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkMaskTest.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkTest.xml b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkTest.xml new file mode 100644 index 0000000..f9e71c1 --- /dev/null +++ b/trunk/target/surefire-reports/TEST-com.googlecode.ipv6.IPv6NetworkTest.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressPoolTest.txt b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressPoolTest.txt new file mode 100644 index 0000000..2ae4c11 --- /dev/null +++ b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressPoolTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: com.googlecode.ipv6.IPv6AddressPoolTest +------------------------------------------------------------------------------- +Tests run: 13, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.08 sec diff --git a/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressRangeTest.txt b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressRangeTest.txt new file mode 100644 index 0000000..4e16a02 --- /dev/null +++ b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressRangeTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: com.googlecode.ipv6.IPv6AddressRangeTest +------------------------------------------------------------------------------- +Tests run: 16, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.08 sec diff --git a/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressTest.txt b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressTest.txt new file mode 100644 index 0000000..f6e4a36 --- /dev/null +++ b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6AddressTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: com.googlecode.ipv6.IPv6AddressTest +------------------------------------------------------------------------------- +Tests run: 40, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.47 sec diff --git a/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkHelpersTest.txt b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkHelpersTest.txt new file mode 100644 index 0000000..9b7917c --- /dev/null +++ b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkHelpersTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: com.googlecode.ipv6.IPv6NetworkHelpersTest +------------------------------------------------------------------------------- +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 sec diff --git a/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkMaskTest.txt b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkMaskTest.txt new file mode 100644 index 0000000..399ccf5 --- /dev/null +++ b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkMaskTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: com.googlecode.ipv6.IPv6NetworkMaskTest +------------------------------------------------------------------------------- +Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 sec diff --git a/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkTest.txt b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkTest.txt new file mode 100644 index 0000000..3f6180b --- /dev/null +++ b/trunk/target/surefire-reports/com.googlecode.ipv6.IPv6NetworkTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: com.googlecode.ipv6.IPv6NetworkTest +------------------------------------------------------------------------------- +Tests run: 11, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.18 sec diff --git a/trunk/target/test-classes/com/googlecode/ipv6/IPv6AddressPoolTest.class b/trunk/target/test-classes/com/googlecode/ipv6/IPv6AddressPoolTest.class new file mode 100644 index 0000000000000000000000000000000000000000..a3ca7b940fcdf284c4d21e40ae54ff5e52788430 GIT binary patch literal 7092 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 literal 0 HcmV?d00001 diff --git a/trunk/target/test-classes/com/googlecode/ipv6/IPv6AddressRangeTest.class b/trunk/target/test-classes/com/googlecode/ipv6/IPv6AddressRangeTest.class new file mode 100644 index 0000000000000000000000000000000000000000..61a05f876e041defcb4ef5627814429a794a15e3 GIT binary patch literal 8418 zcmc&(33yc16+U;e%w-ruc!aQuAPCvWWF`yY1(1NC!6Yc5Sg=K2CXX;MOPqzxT9?|* zrLAJMDsHVx7rUr6M61@SU9@(wcC}TzSZ%FaS6i#%f8KlZ=DnFo6TZ*y>kPT?-gD1A z=ReCm_rBq=x9@#`h(e;rM?>^wNni2NJo>7nuleW>x>M3!lD;nKZXON$=rD~)x<}Hz zlD;A7J|^5R=>bXKl=L9;d`r?pk{*`yh@@{z`VP~+JCVLekNW5_`o5&cCH;VjKb%NE zq91efgqMCI=}AdHmGm=7Kj+zBF!x9qknv}tkA6wNlJu0MU-Rs5c=l;?)>&pt}fi<15#=_N@oOL|4ptCC)0uD?q9 zo20)>`iG={O8S?i*CqX1(tjkqA?d%8-jwu~q_-s`AED<(?em*N;HDx{bsMI|(d$x$Kf%odW|&J(b#^#Rv6`dMe!^s4|?0r_#wxINcTB ztwkdPf@W;U#M68I>ok$J_c4h!FU`der-XT4l*0FLy_fBoM z7KlQApeq{H2eoKtaxfFqpIK$jsWk;L3&EtY@>)^E4m zr30tv0<^xg7T(pP4H@qCirIoDz|%uoQs0;WizaB{SgH;D&>{Nq7slU!5&2^g>QrPu z%$SzS^vCsd>MSjq)U|70b7bCVfh*2$RCLmOgHvvF}>4FctOi+9ImhfKB_yMyQRa}jYCO&H!{saET}BWI|-ClX`Ipn(AMD$;2>3o7={ z&}%R;BYzpzB4c%nYJ81;D`4SkNoBi`&bD1k1^HA{In?;+0#V}?wSGDv>b#=fFB-&R zgS#De8ux8vhzECVnb#>X*X@Yxp3>c{8k zW^LD8B3itn)i2t_5>!i7HKLAOI3Qq1gMc5bxI>#?r~)NpQ69?ChKPh}q6#)O8ei00 zHzm}H08DYyngYR46KCKuuUPIEE5wO@v64O7=@+ZSYCqjfpT&VkgQ(6LXH%O^AcYea zn8FDQ(6j;pQyn%#dYeIqRc?B-DIKAA z)7wn(D0_MEL#6`6-l-SdhI|CTN#-m8oF;&Gif1qe9q31`687D|xsu@;EAtFwxCT8x zYz#NMz-dXa4P;{i*xVD=iXbZR3b6*YKvVnGusXnX!s_deewh2SOde+)vnzyOtQ9Bw z#VOo$iFJN)s^}I}Ge&hZE<=1Z!M!wh@m$}(6W38>xj}MW?r=jLk4V(`?a4%}FP)6U z2L-iSN3n6OHHjUyV;!@ohm|a3Z6ujWcg6?0HHNvfX3TYCGK{G@d&gWbwzAqSfSJ3| zccxN$5-@$5(b<^H=(w2HY~jn#M3c5wi>5%V9aFZ6f)zB6$qRSpf@R%jE8G<0jR=?U zYV+M=dlDBrz7qzrnEfWcHD_ml5LdIBt}ccx%@>3OZZOp~PBr%Z57)OHTB=vy3&Zi& z1;C|oV^EdlHv(^_6~a1h(}A|iFe0XEeNYDyFW$5=`ugp-cGax2K;s{MMY*jMKsT0%-yJ-(bg7#vu$5^}^PhLDp@r+Q3Qi^7T%Ff7%@qvM; zjw-0$A!?E(Y9Hn%Lco6fofD=H;Bl@k`$GRQRvK6jGxz;^qh5b$O{XaXgUSahUgS(p>5O#2es3uNOf3zxx-?1?S8Bi z^g-L$>nvk6w^0>YrIXzB${gKg)Z|gj1441$~|k zIz=Tgf~eCC&Ka&@no+QWfZYVJo8i4P9e|5_?*bd}T^8VdWp4Me zXNGCUJv39$2+b;W&zk8x+U#ui+7fduui=!>Tbnb)OoeSUhx%z54bT?aPJ3yG!!?%uUE&c1EaVnW^*Gtjp%~G~7e@LFXEpg3eq)57NBei-b6I zp0{X<@Y2O^Aj!Gb)mtNZ^g|ta3acEAvg<-R5Y4IqFePaLo0ZBWq4At#25n zg*TA5^bnQ8&x`68V|>sto>A&1G~_Wfoj2E*+$9P7mA;Ce( zxp@Umg1P%plFy;psJC@=9xbH{sSA$X4A<_2Tld4Um%x<=;mF(RV!98b$LUgfhAuNg z(PFyHa(e|mfw{}z_Sy6>eF8lXq~1-RM6U$0Z$mM>48h}|v{Ka(T0>=Cy4*`w*#C%D zii(wDQnocapx|HSN|6`61KH>y)@BLXP(?K(RHxK)oEpri4b$QgYOJCFPjK!lLH9%m z6O-xuVQMkgwK}JByTjb(S0LXGAk(g-)9EV5&e%|NXIyC`yc7tzrZp&S3}K0>qg!bo zp`|0F_B0^09V4_1Q0ur`f0&l%f@SW^g9z63G>vYcM6?d%0Q9&1pvg`hI|Z0H7ZN=!XINk#`C7!7ONjH+UmG zZdOirf!@GS`?%T2&3m}n#LXGpyqBBJ+-%|IOm5!C&HK?*dhe&Ln@g0l(C^z^s%$f! zWr}7z%awlP=~cqUQyO0B+gw?0cm^s5#+8JR!ZnYfI6aNM@C^3NvkuqXY$xFXD+wyZQgC31ES}#BVRC(RGVvUBt8p?d!OE5 zYuf{DyiaSDLDsgz(uTqj!Qaji+SOB!^5-rkrh2oKyae?x(@c7Wj-ywphF)_xq}GNp z%YrczXT^;o?_nTnHA@1oU4gAH9LVyoKw@5&SZdkx4 z(mdGpIiTf>$U4gw?%jgZjPI%I=vL!w^5M328~94>0%>v`0vDfA6Ug%>P4&{}Yv>CY NdQidyN*MQUe+PPG$nO9E literal 0 HcmV?d00001 diff --git a/trunk/target/test-classes/com/googlecode/ipv6/IPv6AddressTest.class b/trunk/target/test-classes/com/googlecode/ipv6/IPv6AddressTest.class new file mode 100644 index 0000000000000000000000000000000000000000..f93a9cc23ad0a9d1ada5fe94f25d59d9c26cdbc4 GIT binary patch literal 11643 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 literal 0 HcmV?d00001 diff --git a/trunk/target/test-classes/com/googlecode/ipv6/IPv6NetworkHelpersTest.class b/trunk/target/test-classes/com/googlecode/ipv6/IPv6NetworkHelpersTest.class new file mode 100644 index 0000000000000000000000000000000000000000..ccd06f746f59c59788029ef23456ac4fcffe1eda GIT binary patch literal 1057 zcma)4-%ry}6#njh)>35*L2)W$$k-;*F%V5LCJTYMWI-Zi559HVUAePsvF)Z$%zw!z z7ax4{#Xrh;+SN^>1nH}TDEK)>I)3%b>Q1AqsNvH}IQBGn@p}B1{L^LgMsn9?=bbNCrP<~sfsr9^E zF8dA(Q%DQ2inguoT*mi(-w-eT|CETb-@9t+mZ83Gc6rNVSiUO0+HO1Cr8&tR$L^hY zj<5`dr-k}7#~9ozUinjD4*H(_Rb?)JCc{DD+HBW46l)BN1K4tOJBe~2hVAei2%%Co^)mGfZJFg ziz-uaBnbYFXz(_i!>4p)glHf}h>Z|W4bzFgkif@>L!XOrRC0nu$3fBrNM+ME{50|u zsitRqM42GdwsVlE#VobGf;Hsu46CS-_7-`VSjPnle^45RlT AuK)l5 literal 0 HcmV?d00001 diff --git a/trunk/target/test-classes/com/googlecode/ipv6/IPv6NetworkMaskTest.class b/trunk/target/test-classes/com/googlecode/ipv6/IPv6NetworkMaskTest.class new file mode 100644 index 0000000000000000000000000000000000000000..52800a1b38caa033462aa06a380c2b739d0187e4 GIT binary patch literal 1485 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 ME-rqz(|XVU0R3Q<{r~^~ literal 0 HcmV?d00001 diff --git a/trunk/target/test-classes/com/googlecode/ipv6/examples/Examples.class b/trunk/target/test-classes/com/googlecode/ipv6/examples/Examples.class new file mode 100644 index 0000000000000000000000000000000000000000..efaf2019b823fb366e367a522bb40ed216eaab9a GIT binary patch literal 5644 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 literal 0 HcmV?d00001 diff --git a/wiki/WhatsNew.wiki b/wiki/WhatsNew.wiki new file mode 100644 index 0000000..d25d8d2 --- /dev/null +++ b/wiki/WhatsNew.wiki @@ -0,0 +1,33 @@ +#summary New features per release + += v0.15 = + + * new feature: deaggregate IPv6AddressRange in subnets, see [https://code.google.com/p/java-ipv6/issues/detail?id=9 ISSUE-9] + += v0.14 = + + * IPv6AddressRange.size() method added, see [https://code.google.com/p/java-ipv6/issues/detail?id=8 ISSUE-8] + * new feature: split IPv6Network in smaller subnets, see [https://code.google.com/p/java-ipv6/issues/detail?id=10 ISSUE-10] + += v0.13 = + + * bugfix for [https://code.google.com/p/java-ipv6/issues/detail?id=7 ISSUE-7] + += v0.12 = + + * added IPv6Address.isMulticast method + * added IPv6Address.isLinkLocal method + * added IPv6Address.isSiteLocal method + * added IPv6Address.isIPv4Mapped method + * support IPv4-Mapped addresses in toString and fromString (e.g. ::ffff:192.168.0.1) + += v0.11 = + + * construct IPv6Address from byte array + * convert IPv6Address to byte array + * construct IPv6Address from two longs (like the internal representation) + * in toString: use shorthand notation for zeroes on the longest run of zeroes, in stead of on the first run of zeroes + += v0.10 = + + * allow network with zero prefix length (e.g. ::/0) \ No newline at end of file