001/*
002 * JPPF.
003 * Copyright (C) 2005-2018 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.net;
020
021import java.net.*;
022
023import org.jppf.utils.Range;
024
025/**
026 * Represents a pattern used for IPv6 addresses inclusion and exclusion lists.<br/>
027 * A pattern represents a single value or a range of values for each component of an IPv6 address.<br/>
028 * <p>Examples:
029 * <ul>
030 * <li>1080:0:0:0:8:800:200C:417A represents a single IPv6 address</li>
031 * <li>1080:0:0:0:8:800:200C represents all IPv6 addresses in the range 1080:0:0:0:8:800:200C:0 - 1080:0:0:0:8:800:200C:FFFF</li>
032 * <li>1080:0:0:0:8:800 represents all IPv6 addresses in the range 1080:0:0:0:8:800:0:0 - 1080:0:0:0:8:800:FFFF:FFFF</li>
033 * <li>1080:0:0:0:8:800:200C-20FF represents all IP addresses where the first component is equal to 1080, the second to 0, ..., the 7th component in the range 200C - 200FF, and the 8th in the range 0
034 * - FFFF
035 * (equivalent to 1080:0:0:0:8:800:200C-20FF:0-FFFF)</li>
036 * </ul>
037 * <p>Syntax rules:
038 * <p>1. An empty component is considered as a 0-FFFF range. Examples:
039 * <ul>
040 * <li>:2:3:4:5:6:7:8 is equivalent to 0-FFFF:2:3:4:5:6:7:8</li>
041 * <li>1:2:3:4:5::7:8 is equivalent to 1:2:3:4:5:0-FFFF:7:8</li>
042 * <li>1:2:3:4:5:6:7: is equivalent to 1:2:3:4:5:6:7 and to 1:2:3:4:5:6:7:0-FFFF</li>
043 * </ul>
044 * <p>2. Ranges with missing bounds but still including the &quot;-&quot; sign are interpreted as a range with the lower bound
045 * equal to zero for a missing lower bound, and an upper bound equal to 0xFFFF if the upper bound is missing. Examples:
046 * <ul>
047 * <li>-128 is equivalent to 0-128</li>
048 * <li>12- is equivalent to 12-FFFF</li>
049 * <li>- is equivalent to an empty value and to 0-FFFF</li>
050 * </ul>
051 * <p>3. Valid values for range bounds and single values are positive integers in the range 0 ... 0xFFFF. A pattern containing any invalid value will be ignored.
052 * <p>4. A pattern describing more than 8 components or containing characters other than hexadecimal digits, '-', ':' or spaces will be ignored.
053 * @author Laurent Cohen
054 */
055public class IPv6AddressPattern extends AbstractIPAddressPattern {
056  /**
057   * Initialize this object with the specified string pattern.
058   * @param source the source pattern as a string.
059   * @throws IllegalArgumentException if the pattern is null or invalid.
060   */
061  public IPv6AddressPattern(final String source) throws IllegalArgumentException {
062    super(source, PatternConfiguration.IPV6_CONFIGURATION);
063  }
064
065  @Override
066  public boolean matches(final InetAddress ip) {
067    if (!(ip instanceof Inet6Address)) return false;
068    return super.matches(ip);
069  }
070
071  @Override
072  public String toString() {
073    final StringBuilder sb = new StringBuilder();
074    for (int i = 0; i < ranges.size(); i++) {
075      if (i > 0) sb.append(config.getCompSeparator());
076      final Range<Integer> r = ranges.get(i);
077      sb.append(Integer.toHexString(r.getLower()));
078      if (!r.getLower().equals(r.getUpper())) sb.append('-').append(Integer.toHexString(r.getUpper()));
079    }
080    return sb.toString();
081  }
082
083  /**
084   * Main method.
085   * @param args not used.
086   */
087  public static void main(final String[] args) {
088    System.out.println("***** IP v6 *****");
089    final String[] ipv6patterns = { "1080:0:0:0:8:800:200C:417A", ":0::::::", "0:0:aa-bbcc:0:0:0:0:0", "1:2:3:4:5-:6:7:8", };
090    final String ip = "1080:0:0:0:8:800:200C:417A";
091    for (int i = 0; i < ipv6patterns.length; i++) {
092      try {
093        final IPv6AddressPattern p = new IPv6AddressPattern(ipv6patterns[i]);
094        final InetAddress addr = InetAddress.getByName(ip);
095        System.out.println("pattern " + i + " for source '" + ipv6patterns[i] + "' = '" + p + "', ip match = " + p.matches(addr));
096      } catch (final Exception e) {
097        System.out.println("#" + i + " : " + e.getMessage());
098      }
099    }
100  }
101}