mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
04.24.2007 0d23044ef2e0404e841bda74b4508853196080ba
Update a number of files to add the missing svn:eol-style property.  Also, fix
a couple of CDDL/copyright headers. Finally, update the CheckPrecommit Ant
task so that it properly checks for a property that can be used to ignore these
problems and continue with the build.
7 files modified
2177 ■■■■ changed files
opends/resource/uninstall.bat 164 ●●●● patch | view | raw | blame | history
opends/src/build-tools/org/opends/build/tools/CheckPrecommit.java 30 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/authorization/dseecompat/IP.java 264 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/authorization/dseecompat/PatternIP.java 916 ●●●● patch | view | raw | blame | history
opends/tests/functional-tests/shared/java/addAnEntry.java 26 ●●●●● patch | view | raw | blame | history
opends/tests/functional-tests/shared/java/modifyAnAttribute.java 5 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/IPTestCase.java 772 ●●●● patch | view | raw | blame | history
opends/resource/uninstall.bat
@@ -1,82 +1,82 @@
@echo off
rem CDDL HEADER START
rem
rem The contents of this file are subject to the terms of the
rem Common Development and Distribution License, Version 1.0 only
rem (the "License").  You may not use this file except in compliance
rem with the License.
rem
rem You can obtain a copy of the license at
rem trunk/opends/resource/legal-notices/OpenDS.LICENSE
rem or https://OpenDS.dev.java.net/OpenDS.LICENSE.
rem See the License for the specific language governing permissions
rem and limitations under the License.
rem
rem When distributing Covered Code, include this CDDL HEADER in each
rem file and include the License file at
rem trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
rem add the following below this CDDL HEADER, with the fields enclosed
rem by brackets "[]" replaced with your own identifying information:
rem      Portions Copyright [yyyy] [name of copyright owner]
rem
rem CDDL HEADER END
rem
rem
rem      Portions Copyright 2006-2007 Sun Microsystems, Inc.
setlocal
set DIR_HOME=%~dP0.
set INSTANCE_ROOT=%DIR_HOME%
:checkJavaBin
if "%JAVA_BIN%" == "" goto noJavaBin
goto setClassPath
:noJavaBin
if "%JAVA_HOME%" == "" goto noJavaHome
if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
set JAVA_BIN=%JAVA_HOME%\bin\java.exe
goto setClassPath
:noJavaHome
if not exist "%DIR_HOME%\lib\set-java-home.bat" goto noSetJavaHome
call "%DIR_HOME%\lib\set-java-home.bat"
set JAVA_BIN=%JAVA_HOME%\bin\java.exe
goto setClassPath
:noSetJavaHome
echo Error: JAVA_HOME environment variable is not set.
echo        Please set it to a valid Java 5 (or later) installation.
pause
goto end
:noValidJavaHome
echo ERROR:  The detected Java version could not be used.  Please set
echo         JAVA_HOME to to a valid Java 5 (or later) installation.
pause
goto end
:setClassPath
FOR %%x in ("%DIR_HOME%\lib\*.jar") DO call "%DIR_HOME%\lib\setcp.bat" %%x
set CLASSPATH=%DIR_HOME%\classes;%CLASSPATH%
set PATH=%SystemRoot%
rem Test that the provided JDK is 1.5 compatible.
"%JAVA_BIN%" org.opends.server.tools.InstallDS -t > NUL 2>&1
if not %errorlevel% == 0 goto noValidJavaHome
if "%~1" == "" goto callLaunch
goto callJava
:callLaunch
"%DIR_HOME%\lib\winlauncher.exe" launch "%DIR_HOME%" "%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.uninstaller.UninstallLauncher
goto end
:callJava
"%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.uninstaller.UninstallLauncher %*
goto end
:end
@echo off
rem CDDL HEADER START
rem
rem The contents of this file are subject to the terms of the
rem Common Development and Distribution License, Version 1.0 only
rem (the "License").  You may not use this file except in compliance
rem with the License.
rem
rem You can obtain a copy of the license at
rem trunk/opends/resource/legal-notices/OpenDS.LICENSE
rem or https://OpenDS.dev.java.net/OpenDS.LICENSE.
rem See the License for the specific language governing permissions
rem and limitations under the License.
rem
rem When distributing Covered Code, include this CDDL HEADER in each
rem file and include the License file at
rem trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
rem add the following below this CDDL HEADER, with the fields enclosed
rem by brackets "[]" replaced with your own identifying information:
rem      Portions Copyright [yyyy] [name of copyright owner]
rem
rem CDDL HEADER END
rem
rem
rem      Portions Copyright 2006-2007 Sun Microsystems, Inc.
setlocal
set DIR_HOME=%~dP0.
set INSTANCE_ROOT=%DIR_HOME%
:checkJavaBin
if "%JAVA_BIN%" == "" goto noJavaBin
goto setClassPath
:noJavaBin
if "%JAVA_HOME%" == "" goto noJavaHome
if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
set JAVA_BIN=%JAVA_HOME%\bin\java.exe
goto setClassPath
:noJavaHome
if not exist "%DIR_HOME%\lib\set-java-home.bat" goto noSetJavaHome
call "%DIR_HOME%\lib\set-java-home.bat"
set JAVA_BIN=%JAVA_HOME%\bin\java.exe
goto setClassPath
:noSetJavaHome
echo Error: JAVA_HOME environment variable is not set.
echo        Please set it to a valid Java 5 (or later) installation.
pause
goto end
:noValidJavaHome
echo ERROR:  The detected Java version could not be used.  Please set
echo         JAVA_HOME to to a valid Java 5 (or later) installation.
pause
goto end
:setClassPath
FOR %%x in ("%DIR_HOME%\lib\*.jar") DO call "%DIR_HOME%\lib\setcp.bat" %%x
set CLASSPATH=%DIR_HOME%\classes;%CLASSPATH%
set PATH=%SystemRoot%
rem Test that the provided JDK is 1.5 compatible.
"%JAVA_BIN%" org.opends.server.tools.InstallDS -t > NUL 2>&1
if not %errorlevel% == 0 goto noValidJavaHome
if "%~1" == "" goto callLaunch
goto callJava
:callLaunch
"%DIR_HOME%\lib\winlauncher.exe" launch "%DIR_HOME%" "%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.uninstaller.UninstallLauncher
goto end
:callJava
"%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.uninstaller.UninstallLauncher %*
goto end
:end
opends/src/build-tools/org/opends/build/tools/CheckPrecommit.java
@@ -190,7 +190,6 @@
    if (! eolStyleProblemFiles.isEmpty())
    {
      fail = true;
      System.err.println("WARNING:  Potential svn:eol-style updates needed " +
                         "for the following files:");
      for (String filename : eolStyleProblemFiles)
@@ -198,14 +197,19 @@
        System.err.println("     " + filename);
      }
      System.err.println("Fix svn:eol-style problems before proceeding, or " +
                         "use '-D" + IGNORE_EOLSTYLE_ERRORS_PROPERTY +
                         "=true' to ignore svn eol-style warnings.");
      String ignoreProp =
           getProject().getProperty(IGNORE_EOLSTYLE_ERRORS_PROPERTY);
      if ((ignoreProp == null) || (! ignoreProp.equalsIgnoreCase("true")))
      {
        fail = true;
        System.err.println("Fix svn:eol-style problems before proceeding, or " +
                           "use '-D" + IGNORE_EOLSTYLE_ERRORS_PROPERTY +
                           "=true' to ignore svn eol-style warnings.");
      }
    }
    if (! copyrightProblemFiles.isEmpty())
    {
      fail = true;
      System.err.println("WARNING:  Potential copyright year updates needed " +
                         "for the following files:");
      for (String filename : copyrightProblemFiles)
@@ -213,9 +217,15 @@
        System.err.println("     " + filename);
      }
      System.err.println("Fix copyright date problems before proceeding, or " +
                         "use '-D" + IGNORE_COPYRIGHT_ERRORS_PROPERTY +
                         "=true' to ignore copyright warnings.");
      String ignoreProp =
           getProject().getProperty(IGNORE_COPYRIGHT_ERRORS_PROPERTY);
      if ((ignoreProp == null) || (! ignoreProp.equalsIgnoreCase("true")))
      {
        fail = true;
        System.err.println("Fix copyright date problems before proceeding, " +
                           "or use '-D" + IGNORE_COPYRIGHT_ERRORS_PROPERTY +
                           "=true' to ignore copyright warnings.");
      }
    }
    if (fail)
@@ -274,9 +284,9 @@
    String filePath = file.getAbsolutePath();
    if (filePath.startsWith(workspacePath.getPath()))
    if (filePath.startsWith(workspacePath.getPath() + "/"))
    {
      filePath = filePath.substring(workspacePath.getPath().length());
      filePath = filePath.substring(workspacePath.getPath().length() + 1);
    }
opends/src/server/org/opends/server/authorization/dseecompat/IP.java
@@ -1,132 +1,132 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.authorization.dseecompat;
import static org.opends.server.messages.AciMessages.*;
import static org.opends.server.messages.MessageHandler.getMessage;
import java.util.regex.Pattern;
import java.util.*;
import java.net.InetAddress;
/**
 * This class represents a single ACI's IP bind rule expression. It is possble
 * for that expression to contain several IP addresses to evaluate, so the
 * class contains a list of classes that can evaluate a remote clients IP
 * address for each IP address parsed from the bind rule.
 */
public class IP implements KeywordBindRule {
    /*
      Regular expression used to do a quick check on the characters in a
      bind rule address. These are all of the valid characters that may
      appear in an bind rule address part.
    */
    private  static final String ipRegEx =
            "((?i)[\\.{1}[a-f]\\d:\\+{1}\\*/{1}\\t\\[{1}\\]{1}]+(?-i))";
    /*
      List of the pattern classes, one for each address decoded from the
      bind rule.
    */
    private List<PatternIP> patternIPList=null;
    /*
      The type of the bind rule (!= or =).
     */
    private EnumBindRuleType type=null;
    /**
     * Create a class representing the IP bind rule expressions for this ACI.
     * @param patternIPList A list of PatternIP objects representing the IP
     *                      bind rule expressions decoded from ACI.
     * @param type An enumeration representing the expression type.
     */
    private IP(List<PatternIP> patternIPList, EnumBindRuleType type) {
        this.patternIPList=patternIPList;
        this.type=type;
    }
    /**
     * Decodes the provided IP bind rule expression string and returns an
     * IP class the can be used to evaluate remote clients IP addresses.
     *
     * @param expr The expression string from the ACI IP bind rule.
     * @param type An enmumeration representing the expression type.
     * @return  A class that can be used to evaluate remote clients IP
     *          addresses.
     * @throws AciException  If there is a parsing error.
     */
    public static KeywordBindRule decode(String expr, EnumBindRuleType type)
            throws AciException  {
        //Split on the ','.
        String[] ipStrs=expr.split("\\,", -1);
        List<PatternIP> patternIPList= new LinkedList<PatternIP>();
        for (String ipStr : ipStrs) {
            if (!Pattern.matches(ipRegEx, ipStr)) {
                int msgID = MSGID_ACI_SYNTAX_INVALID_IP_EXPRESSION;
                String message = getMessage(msgID, expr);
                throw new AciException(msgID, message);
            }
            PatternIP ipPattern = PatternIP.decode(ipStr);
            patternIPList.add(ipPattern);
        }
        return new IP(patternIPList, type);
    }
    /**
     * Perform an evaluation using the provided evaluation context's remote
     * IP address information.
     *
     * @param evalCtx An evaluation context containing the remote clients
     * IP address information.
     *
     * @return An enumeration representing if the address matched.
     */
    public EnumEvalResult evaluate(AciEvalContext evalCtx) {
        InetAddress remoteAddr=evalCtx.getRemoteAddress();
        return evaluate(remoteAddr);
    }
    /**
     * Perform an evaluation using the InetAddress.
     *
     * @param addr  The InetAddress to evaluate against PatternIP classes.
     * @return  An enumeration representing if the address matched one
     *          of the patterns.
     */
    EnumEvalResult evaluate(InetAddress addr) {
        EnumEvalResult matched=EnumEvalResult.FALSE;
        Iterator<PatternIP> it=patternIPList.iterator();
        for(; it.hasNext() && matched != EnumEvalResult.TRUE &&
                matched != EnumEvalResult.ERR;) {
            PatternIP patternIP=it.next();
            matched=patternIP.evaluate(addr);
        }
        return matched.getRet(type, false);
    }
}
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.authorization.dseecompat;
import static org.opends.server.messages.AciMessages.*;
import static org.opends.server.messages.MessageHandler.getMessage;
import java.util.regex.Pattern;
import java.util.*;
import java.net.InetAddress;
/**
 * This class represents a single ACI's IP bind rule expression. It is possble
 * for that expression to contain several IP addresses to evaluate, so the
 * class contains a list of classes that can evaluate a remote clients IP
 * address for each IP address parsed from the bind rule.
 */
public class IP implements KeywordBindRule {
    /*
      Regular expression used to do a quick check on the characters in a
      bind rule address. These are all of the valid characters that may
      appear in an bind rule address part.
    */
    private  static final String ipRegEx =
            "((?i)[\\.{1}[a-f]\\d:\\+{1}\\*/{1}\\t\\[{1}\\]{1}]+(?-i))";
    /*
      List of the pattern classes, one for each address decoded from the
      bind rule.
    */
    private List<PatternIP> patternIPList=null;
    /*
      The type of the bind rule (!= or =).
     */
    private EnumBindRuleType type=null;
    /**
     * Create a class representing the IP bind rule expressions for this ACI.
     * @param patternIPList A list of PatternIP objects representing the IP
     *                      bind rule expressions decoded from ACI.
     * @param type An enumeration representing the expression type.
     */
    private IP(List<PatternIP> patternIPList, EnumBindRuleType type) {
        this.patternIPList=patternIPList;
        this.type=type;
    }
    /**
     * Decodes the provided IP bind rule expression string and returns an
     * IP class the can be used to evaluate remote clients IP addresses.
     *
     * @param expr The expression string from the ACI IP bind rule.
     * @param type An enmumeration representing the expression type.
     * @return  A class that can be used to evaluate remote clients IP
     *          addresses.
     * @throws AciException  If there is a parsing error.
     */
    public static KeywordBindRule decode(String expr, EnumBindRuleType type)
            throws AciException  {
        //Split on the ','.
        String[] ipStrs=expr.split("\\,", -1);
        List<PatternIP> patternIPList= new LinkedList<PatternIP>();
        for (String ipStr : ipStrs) {
            if (!Pattern.matches(ipRegEx, ipStr)) {
                int msgID = MSGID_ACI_SYNTAX_INVALID_IP_EXPRESSION;
                String message = getMessage(msgID, expr);
                throw new AciException(msgID, message);
            }
            PatternIP ipPattern = PatternIP.decode(ipStr);
            patternIPList.add(ipPattern);
        }
        return new IP(patternIPList, type);
    }
    /**
     * Perform an evaluation using the provided evaluation context's remote
     * IP address information.
     *
     * @param evalCtx An evaluation context containing the remote clients
     * IP address information.
     *
     * @return An enumeration representing if the address matched.
     */
    public EnumEvalResult evaluate(AciEvalContext evalCtx) {
        InetAddress remoteAddr=evalCtx.getRemoteAddress();
        return evaluate(remoteAddr);
    }
    /**
     * Perform an evaluation using the InetAddress.
     *
     * @param addr  The InetAddress to evaluate against PatternIP classes.
     * @return  An enumeration representing if the address matched one
     *          of the patterns.
     */
    EnumEvalResult evaluate(InetAddress addr) {
        EnumEvalResult matched=EnumEvalResult.FALSE;
        Iterator<PatternIP> it=patternIPList.iterator();
        for(; it.hasNext() && matched != EnumEvalResult.TRUE &&
                matched != EnumEvalResult.ERR;) {
            PatternIP patternIP=it.next();
            matched=patternIP.evaluate(addr);
        }
        return matched.getRet(type, false);
    }
}
opends/src/server/org/opends/server/authorization/dseecompat/PatternIP.java
@@ -1,458 +1,458 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.authorization.dseecompat;
import static org.opends.server.messages.AciMessages.*;
import static org.opends.server.messages.MessageHandler.getMessage;
import java.util.BitSet;
import java.util.HashMap;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.Inet6Address;
/**
 * A class representing a single IP address parsed from a IP bind rule
 * expression. The class can be used to evaluate a remote clients IP address
 * using the information parsed from the IP bind rule expression.
 */
public class PatternIP {
    /**
     * Enumeration that represents if the pattern is IPv5 or
     * IPv4.
     */
     enum IPType {
        IPv4, IPv6
    }
    /*
      The IP address type (v6 or v4).
     */
    private IPType ipType;
    /*
      IPv4 sizes of addresses and prefixes.
     */
    private static int IN4ADDRSZ = 4;
    private static int IPV4MAXPREFIX = 32;
    /*
      IPv6 sizes of addresses and prefixes.
     */
    private static int IN6ADDRSZ = 16;
    private static int IPV6MAXPREFIX = 128;
    /*
      Byte arrays used to match the remote IP address. The ruleAddrByte array
      contains the bytes of the address from the ACI IP bind rule. The
      rulePrefixBytes array contains the bytes of the cidr prefix or netmask
      representation.
     */
    private byte[] ruleAddrBytes, rulePrefixBytes;
    /*
      Bit set that holds the wild-card information of processed IPv4 addresses.
     */
    private BitSet wildCardBitSet;
    /*
      Hash map of valid netmask strings. Used in parsing netmask values.
     */
    private static HashMap<String,String> validNetMasks =
                                               new HashMap<String, String>();
    /*
     Initialize valid netmask hash map.
     */
    static {
        initNetMask(
                "255.255.255.255",
                "255.255.255.254",
                "255.255.255.252",
                "255.255.255.248",
                "255.255.255.240",
                "255.255.255.224",
                "255.255.255.192",
                "255.255.255.128",
                "255.255.255.0",
                "255.255.254.0",
                "255.255.252.0",
                "255.255.248.0",
                "255.255.240.0",
                "255.255.224.0",
                "255.255.192.0",
                "255.255.128.0",
                "255.255.0.0",
                "255.254.0.0",
                "255.252.0.0",
                "255.248.0.0",
                "255.240.0.0",
                "255.224.0.0",
                "255.192.0.0",
                "255.128.0.0",
                "255.0.0.0",
                "254.0.0.0",
                "252.0.0.0",
                "248.0.0.0",
                "240.0.0.0",
                "224.0.0.0",
                "192.0.0.0",
                "128.0.0.0",
                "0.0.0.0"
        );
    }
    /**
     * Load the valid netmask hash map with the 33 possible valid netmask
     * strings.
     *
      * @param lines The strings representing the valid netmasks.
     */
    private static void initNetMask(String... lines) {
        for(String line : lines) {
            validNetMasks.put(line, line);
        }
    }
    /**
     * Create a class that can be used to evaluate an IP address using the
     * information decoded from the ACI IP bind rule expression.
     *
     * @param ipType The type of the ACI IP address (IPv4 or 6).
     * @param ruleAddrBytes Byte array representing the ACI IP address.
     * @param rulePrefixBytes Prefix byte array corresponding to the bits set
     *                        by the cidr prefix or netmask.
     * @param wildCardBitSet Bit set holding IPv4 wild-card information.
     */
    private PatternIP(IPType ipType, byte[] ruleAddrBytes,
                      byte[] rulePrefixBytes, BitSet wildCardBitSet) {
       this.ipType=ipType;
       this.ruleAddrBytes=ruleAddrBytes;
       this.rulePrefixBytes=rulePrefixBytes;
       this.wildCardBitSet=wildCardBitSet;
    }
    /**
     * Decode the provided address expression string and create a class that
     * can be used to perform an evaluation of an IP address based on the
     * decoded expression string information.
     *
     * @param expr The address expression string from the ACI IP bind rule.
     * @return A class that can evaluate a remote clients IP address using the
     *         expression's information.
     * @throws AciException If the address expression is invalid.
     */
    public static
    PatternIP decode(String expr)  throws AciException {
        IPType ipType=IPType.IPv4;
        byte[] prefixBytes;
        String addrStr;
        if(expr.indexOf(':') != -1)
            ipType = IPType.IPv6;
        if(expr.indexOf('/') != -1) {
            String prefixStr=null;
            String[] s = expr.split("[/]", -1);
            if(s.length == 2) prefixStr=s[1];
            int prefix = getPrefixValue(ipType, s.length, expr, prefixStr);
            prefixBytes=getPrefixBytes(prefix, ipType);
            addrStr=s[0];
        } else if(expr.indexOf('+') != -1) {
            String netMaskStr=null;
            String[] s = expr.split("[+]", -1);
            if(s.length == 2)
                netMaskStr=s[1];
            prefixBytes=getNetmaskBytes(netMaskStr, s.length, expr);
            addrStr=s[0];
        } else {
            int prefix = getPrefixValue(ipType, 1, expr, null);
            prefixBytes=getPrefixBytes(prefix, ipType);
            addrStr=expr;
        }
        //Set the bit set size fo IN6ADDRSZ even though only 4 positions are
        //used.
        BitSet wildCardBitSet = new BitSet(IN6ADDRSZ);
        byte[] addrBytes;
        if(ipType == IPType.IPv4)
            addrBytes = procIPv4Addr(addrStr, wildCardBitSet, expr);
        else {
            addrBytes=procIPv6Addr(addrStr, expr);
            //The IPv6 address processed above might be a IPv4-compatible
            //address, in which case only 4 bytes will be returned in the
            //address byte  array. Ignore any IPv6 prefix.
            if(addrBytes.length == IN4ADDRSZ) {
                ipType=IPType.IPv4;
                prefixBytes=getPrefixBytes(IPV4MAXPREFIX, ipType);
            }
        }
        return new PatternIP(ipType, addrBytes, prefixBytes, wildCardBitSet);
    }
    /**
     * Process the IP address prefix part of the expression. Handles if there is
     * no prefix in the expression.
     *
     * @param ipType The type of the expression, either IPv6 or IPv4.
     * @param numParts The number of parts in the IP address expression.
     *                 1 if there isn't a prefix, and 2 if there is. Anything
     *                 else is an error (i.e., 254.244.123.234/7/6).
     * @param expr The original expression from the bind rule.
     * @param prefixStr The string representation of the prefix part of the
     *                  IP address.
     * @return  An integer value determined from the prefix string.
     * @throws AciException If the prefix string is invalid.
     */
    private static int
    getPrefixValue(IPType ipType, int numParts, String expr, String prefixStr)
    throws AciException {
        int prefix = IPV4MAXPREFIX;
        int maxPrefix= IPV4MAXPREFIX;
        if(ipType == IPType.IPv6) {
            prefix= IPV6MAXPREFIX;
            maxPrefix=IPV6MAXPREFIX;
        }
        try {
            //Can only have one prefix value and one address string.
            if((numParts  < 1) || (numParts > 2) ) {
                int msgID = MSGID_ACI_SYNTAX_INVALID_PREFIX_FORMAT;
                String message = getMessage(msgID, expr);
                throw new AciException(msgID, message);
            }
            if(prefixStr != null)
                prefix = Integer.parseInt(prefixStr);
            //Must be between 0 to maxprefix.
            if((prefix < 0) || (prefix > maxPrefix)) {
                int msgID=MSGID_ACI_SYNTAX_INVALID_PREFIX_VALUE;
                String message = getMessage(msgID, expr);
                throw new AciException(msgID, message);
            }
        } catch(NumberFormatException nfex) {
            int msgID=MSGID_ACI_SYNTAX_PREFIX_NOT_NUMERIC;
            String msg = getMessage(msgID, expr);
            throw new AciException(msgID,msg);
        }
        return prefix;
    }
    /**
     * Determine the prefix bit mask based on the provided prefix value. Handles
     * both IPv4 and IPv6 prefix values.
     *
     * @param prefix  The value of the prefix parsed from the address
     *                expression.
     * @param ipType  The type of the prefix, either IPv6 or IPv4.
     * @return A byte array representing the prefix bit mask used to match
     *         IP addresses.
     */
    private static byte[] getPrefixBytes(int prefix, IPType ipType) {
        int i;
        int maxSize=IN4ADDRSZ;
        if(ipType==IPType.IPv6)
            maxSize= IN6ADDRSZ;
        byte[] prefixBytes=new byte[maxSize];
        for(i=0;prefix > 8 ; i++) {
            prefixBytes[i] = (byte) 0xff;
            prefix -= 8;
        }
        prefixBytes[i] = (byte) ((0xff) << (8 - prefix));
        return prefixBytes;
    }
    /**
     * Process the specified netmask string. Only pertains to IPv4 address
     * expressions.
     *
     * @param netmaskStr String represntation of the netmask parsed from the
     *                   address expression.
     * @param numParts The number of parts in the IP address expression.
     *                 1 if there isn't a netmask, and 2 if there is. Anything
     *                 else is an error (i.e., 254.244.123.234++255.255.255.0).
     * @param expr The original expression from the bind rule.
     * @return A byte array representing the netmask bit mask used to match
     *         IP addresses.
     * @throws AciException If the netmask string is invalid.
     */
    private static
    byte[] getNetmaskBytes(String netmaskStr, int numParts, String expr)
    throws AciException {
        byte[] netmaskBytes=new byte[IN4ADDRSZ];
        //Look up the string in the valid netmask hash table. If it isn't
        //there it is an error.
        if(!validNetMasks.containsKey(netmaskStr)) {
            int id=MSGID_ACI_SYNTAX_INVALID_NETMASK;
            String message = getMessage(id, expr);
            throw new AciException(id, message);
        }
        //Can only have one netmask value and one address string.
        if((numParts  < 1) || (numParts > 2) ) {
            int msgID = MSGID_ACI_SYNTAX_INVALID_NETMASK_FORMAT;
            String message = getMessage(msgID, expr);
            throw new AciException(msgID, message);
        }
        String[] s = netmaskStr.split("\\.", -1);
        try {
            for(int i=0; i < IN4ADDRSZ; i++) {
                String quad=s[i].trim();
                long val=Integer.parseInt(quad);
                netmaskBytes[i] = (byte) (val & 0xff);
            }
        } catch (NumberFormatException nfex) {
            int id=MSGID_ACI_SYNTAX_IPV4_NOT_NUMERIC;
            String message = getMessage(id, expr);
            throw new AciException(id, message);
        }
        return netmaskBytes;
    }
    /**
     * Process the provided IPv4 address string parsed from the IP bind rule
     * address expression. It returns a byte array corresponding to the
     * address string.  The specified bit set represents wild-card characters
     * '*' found in the string.
     *
     * @param addrStr  A string representing an IPv4 address.
     * @param wildCardBitSet A bit set used to save wild-card information.
     * @param expr The original expression from the IP bind rule.
     * @return A address byte array that can be used along with the prefix bit
     *         mask to evaluate an IPv4 address.
     *
     * @throws AciException If the address string is not a valid IPv4 address
     *                      string.
     */
    private static byte[]
    procIPv4Addr(String addrStr, BitSet wildCardBitSet, String expr)
    throws AciException {
        byte[] addrBytes=new byte[IN4ADDRSZ];
        String[] s = addrStr.split("\\.", -1);
        try {
            if(s.length != IN4ADDRSZ) {
                int id=MSGID_ACI_SYNTAX_INVALID_IPV4_FORMAT;
                String message = getMessage(id, expr);
                throw new AciException(id, message);
            }
            for(int i=0; i < IN4ADDRSZ; i++) {
                String quad=s[i].trim();
                if(quad.equals("*"))
                    wildCardBitSet.set(i) ;
                else {
                    long val=Integer.parseInt(quad);
                    //must be between 0-255
                    if((val < 0) ||  (val > 0xff)) {
                        int id=MSGID_ACI_SYNTAX_INVALID_IPV4_VALUE;
                        String message = getMessage(id, expr);
                        throw new AciException(id, message);
                    }
                    addrBytes[i] = (byte) (val & 0xff);
                }
            }
        } catch (NumberFormatException nfex) {
            int id=MSGID_ACI_SYNTAX_IPV4_NOT_NUMERIC;
            String message = getMessage(id, expr);
            throw new AciException(id, message);
        }
        return addrBytes;
    }
    /**
     * Process the provided IPv6  address string parsed from the IP bind rule
     * IP expression. It returns a byte array corresponding to the
     * address string. Wild-cards are not allowed in IPv6 addresses.
     *
     * @param addrStr A string representing an IPv6 address.
     * @param expr The original expression from the IP bind rule.
     * @return A address byte array that can be used along with the prefix bit
     *         mask to evaluate an IPv6 address.
     * @throws AciException If the address string is not a valid IPv6 address
     *                      string.
     */
    private static byte[]
    procIPv6Addr(String addrStr, String expr) throws AciException {
        if(addrStr.indexOf('*') > -1) {
            int msgID=MSGID_ACI_SYNTAX_IPV6_WILDCARD_INVALID;
            String message = getMessage(msgID, expr);
            throw new AciException(msgID, message);
        }
        byte[] addrBytes;
        try {
            addrBytes=InetAddress.getByName(addrStr).getAddress();
        } catch (UnknownHostException ex) {
            int id=MSGID_ACI_SYNTAX_INVALID_IPV6_FORMAT;
            String message = getMessage(id, expr, ex.getMessage());
            throw new AciException(id, message);
        }
        return addrBytes;
    }
    /**
     * Evaluate the provided IP address against the information processed during
     * the IP bind rule expression decode.
     *
     * @param remoteAddr  A IP address to evaluate.
     * @return An enumeration representing the result of the evaluation.
     */
    public EnumEvalResult evaluate(InetAddress remoteAddr) {
        EnumEvalResult matched=EnumEvalResult.FALSE;
        IPType ipType=IPType.IPv4;
        byte[] addressBytes=remoteAddr.getAddress();
        if(remoteAddr instanceof Inet6Address) {
            ipType=IPType.IPv6;
            Inet6Address addr6 = (Inet6Address) remoteAddr;
            addressBytes= addr6.getAddress();
            if(addr6.isIPv4CompatibleAddress())
                ipType=IPType.IPv4;
        }
        if(ipType != this.ipType)
            return EnumEvalResult.FALSE;
        if(matchAddress(addressBytes))
            matched=EnumEvalResult.TRUE;
        return matched;
    }
    /**
     * Attempt to match the address byte array  using the  prefix bit mask array
     * and the address byte array processed in the decode. Wild-cards take
     * priority over the mask.
     *
     * @param addrBytes IP address byte array.
     * @return True if the remote address matches based on the information
     *         parsed from the IP bind rule expression.
     */
    private boolean matchAddress(byte[] addrBytes) {
        if(wildCardBitSet.cardinality() == IN4ADDRSZ)
            return true;
        for(int i=0;i <rulePrefixBytes.length; i++) {
            if(!wildCardBitSet.get(i)) {
                if((ruleAddrBytes[i] & rulePrefixBytes[i]) !=
                        (addrBytes[i] & rulePrefixBytes[i]))
                    return false;
            }
        }
        return true;
    }
}
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.authorization.dseecompat;
import static org.opends.server.messages.AciMessages.*;
import static org.opends.server.messages.MessageHandler.getMessage;
import java.util.BitSet;
import java.util.HashMap;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.Inet6Address;
/**
 * A class representing a single IP address parsed from a IP bind rule
 * expression. The class can be used to evaluate a remote clients IP address
 * using the information parsed from the IP bind rule expression.
 */
public class PatternIP {
    /**
     * Enumeration that represents if the pattern is IPv5 or
     * IPv4.
     */
     enum IPType {
        IPv4, IPv6
    }
    /*
      The IP address type (v6 or v4).
     */
    private IPType ipType;
    /*
      IPv4 sizes of addresses and prefixes.
     */
    private static int IN4ADDRSZ = 4;
    private static int IPV4MAXPREFIX = 32;
    /*
      IPv6 sizes of addresses and prefixes.
     */
    private static int IN6ADDRSZ = 16;
    private static int IPV6MAXPREFIX = 128;
    /*
      Byte arrays used to match the remote IP address. The ruleAddrByte array
      contains the bytes of the address from the ACI IP bind rule. The
      rulePrefixBytes array contains the bytes of the cidr prefix or netmask
      representation.
     */
    private byte[] ruleAddrBytes, rulePrefixBytes;
    /*
      Bit set that holds the wild-card information of processed IPv4 addresses.
     */
    private BitSet wildCardBitSet;
    /*
      Hash map of valid netmask strings. Used in parsing netmask values.
     */
    private static HashMap<String,String> validNetMasks =
                                               new HashMap<String, String>();
    /*
     Initialize valid netmask hash map.
     */
    static {
        initNetMask(
                "255.255.255.255",
                "255.255.255.254",
                "255.255.255.252",
                "255.255.255.248",
                "255.255.255.240",
                "255.255.255.224",
                "255.255.255.192",
                "255.255.255.128",
                "255.255.255.0",
                "255.255.254.0",
                "255.255.252.0",
                "255.255.248.0",
                "255.255.240.0",
                "255.255.224.0",
                "255.255.192.0",
                "255.255.128.0",
                "255.255.0.0",
                "255.254.0.0",
                "255.252.0.0",
                "255.248.0.0",
                "255.240.0.0",
                "255.224.0.0",
                "255.192.0.0",
                "255.128.0.0",
                "255.0.0.0",
                "254.0.0.0",
                "252.0.0.0",
                "248.0.0.0",
                "240.0.0.0",
                "224.0.0.0",
                "192.0.0.0",
                "128.0.0.0",
                "0.0.0.0"
        );
    }
    /**
     * Load the valid netmask hash map with the 33 possible valid netmask
     * strings.
     *
      * @param lines The strings representing the valid netmasks.
     */
    private static void initNetMask(String... lines) {
        for(String line : lines) {
            validNetMasks.put(line, line);
        }
    }
    /**
     * Create a class that can be used to evaluate an IP address using the
     * information decoded from the ACI IP bind rule expression.
     *
     * @param ipType The type of the ACI IP address (IPv4 or 6).
     * @param ruleAddrBytes Byte array representing the ACI IP address.
     * @param rulePrefixBytes Prefix byte array corresponding to the bits set
     *                        by the cidr prefix or netmask.
     * @param wildCardBitSet Bit set holding IPv4 wild-card information.
     */
    private PatternIP(IPType ipType, byte[] ruleAddrBytes,
                      byte[] rulePrefixBytes, BitSet wildCardBitSet) {
       this.ipType=ipType;
       this.ruleAddrBytes=ruleAddrBytes;
       this.rulePrefixBytes=rulePrefixBytes;
       this.wildCardBitSet=wildCardBitSet;
    }
    /**
     * Decode the provided address expression string and create a class that
     * can be used to perform an evaluation of an IP address based on the
     * decoded expression string information.
     *
     * @param expr The address expression string from the ACI IP bind rule.
     * @return A class that can evaluate a remote clients IP address using the
     *         expression's information.
     * @throws AciException If the address expression is invalid.
     */
    public static
    PatternIP decode(String expr)  throws AciException {
        IPType ipType=IPType.IPv4;
        byte[] prefixBytes;
        String addrStr;
        if(expr.indexOf(':') != -1)
            ipType = IPType.IPv6;
        if(expr.indexOf('/') != -1) {
            String prefixStr=null;
            String[] s = expr.split("[/]", -1);
            if(s.length == 2) prefixStr=s[1];
            int prefix = getPrefixValue(ipType, s.length, expr, prefixStr);
            prefixBytes=getPrefixBytes(prefix, ipType);
            addrStr=s[0];
        } else if(expr.indexOf('+') != -1) {
            String netMaskStr=null;
            String[] s = expr.split("[+]", -1);
            if(s.length == 2)
                netMaskStr=s[1];
            prefixBytes=getNetmaskBytes(netMaskStr, s.length, expr);
            addrStr=s[0];
        } else {
            int prefix = getPrefixValue(ipType, 1, expr, null);
            prefixBytes=getPrefixBytes(prefix, ipType);
            addrStr=expr;
        }
        //Set the bit set size fo IN6ADDRSZ even though only 4 positions are
        //used.
        BitSet wildCardBitSet = new BitSet(IN6ADDRSZ);
        byte[] addrBytes;
        if(ipType == IPType.IPv4)
            addrBytes = procIPv4Addr(addrStr, wildCardBitSet, expr);
        else {
            addrBytes=procIPv6Addr(addrStr, expr);
            //The IPv6 address processed above might be a IPv4-compatible
            //address, in which case only 4 bytes will be returned in the
            //address byte  array. Ignore any IPv6 prefix.
            if(addrBytes.length == IN4ADDRSZ) {
                ipType=IPType.IPv4;
                prefixBytes=getPrefixBytes(IPV4MAXPREFIX, ipType);
            }
        }
        return new PatternIP(ipType, addrBytes, prefixBytes, wildCardBitSet);
    }
    /**
     * Process the IP address prefix part of the expression. Handles if there is
     * no prefix in the expression.
     *
     * @param ipType The type of the expression, either IPv6 or IPv4.
     * @param numParts The number of parts in the IP address expression.
     *                 1 if there isn't a prefix, and 2 if there is. Anything
     *                 else is an error (i.e., 254.244.123.234/7/6).
     * @param expr The original expression from the bind rule.
     * @param prefixStr The string representation of the prefix part of the
     *                  IP address.
     * @return  An integer value determined from the prefix string.
     * @throws AciException If the prefix string is invalid.
     */
    private static int
    getPrefixValue(IPType ipType, int numParts, String expr, String prefixStr)
    throws AciException {
        int prefix = IPV4MAXPREFIX;
        int maxPrefix= IPV4MAXPREFIX;
        if(ipType == IPType.IPv6) {
            prefix= IPV6MAXPREFIX;
            maxPrefix=IPV6MAXPREFIX;
        }
        try {
            //Can only have one prefix value and one address string.
            if((numParts  < 1) || (numParts > 2) ) {
                int msgID = MSGID_ACI_SYNTAX_INVALID_PREFIX_FORMAT;
                String message = getMessage(msgID, expr);
                throw new AciException(msgID, message);
            }
            if(prefixStr != null)
                prefix = Integer.parseInt(prefixStr);
            //Must be between 0 to maxprefix.
            if((prefix < 0) || (prefix > maxPrefix)) {
                int msgID=MSGID_ACI_SYNTAX_INVALID_PREFIX_VALUE;
                String message = getMessage(msgID, expr);
                throw new AciException(msgID, message);
            }
        } catch(NumberFormatException nfex) {
            int msgID=MSGID_ACI_SYNTAX_PREFIX_NOT_NUMERIC;
            String msg = getMessage(msgID, expr);
            throw new AciException(msgID,msg);
        }
        return prefix;
    }
    /**
     * Determine the prefix bit mask based on the provided prefix value. Handles
     * both IPv4 and IPv6 prefix values.
     *
     * @param prefix  The value of the prefix parsed from the address
     *                expression.
     * @param ipType  The type of the prefix, either IPv6 or IPv4.
     * @return A byte array representing the prefix bit mask used to match
     *         IP addresses.
     */
    private static byte[] getPrefixBytes(int prefix, IPType ipType) {
        int i;
        int maxSize=IN4ADDRSZ;
        if(ipType==IPType.IPv6)
            maxSize= IN6ADDRSZ;
        byte[] prefixBytes=new byte[maxSize];
        for(i=0;prefix > 8 ; i++) {
            prefixBytes[i] = (byte) 0xff;
            prefix -= 8;
        }
        prefixBytes[i] = (byte) ((0xff) << (8 - prefix));
        return prefixBytes;
    }
    /**
     * Process the specified netmask string. Only pertains to IPv4 address
     * expressions.
     *
     * @param netmaskStr String represntation of the netmask parsed from the
     *                   address expression.
     * @param numParts The number of parts in the IP address expression.
     *                 1 if there isn't a netmask, and 2 if there is. Anything
     *                 else is an error (i.e., 254.244.123.234++255.255.255.0).
     * @param expr The original expression from the bind rule.
     * @return A byte array representing the netmask bit mask used to match
     *         IP addresses.
     * @throws AciException If the netmask string is invalid.
     */
    private static
    byte[] getNetmaskBytes(String netmaskStr, int numParts, String expr)
    throws AciException {
        byte[] netmaskBytes=new byte[IN4ADDRSZ];
        //Look up the string in the valid netmask hash table. If it isn't
        //there it is an error.
        if(!validNetMasks.containsKey(netmaskStr)) {
            int id=MSGID_ACI_SYNTAX_INVALID_NETMASK;
            String message = getMessage(id, expr);
            throw new AciException(id, message);
        }
        //Can only have one netmask value and one address string.
        if((numParts  < 1) || (numParts > 2) ) {
            int msgID = MSGID_ACI_SYNTAX_INVALID_NETMASK_FORMAT;
            String message = getMessage(msgID, expr);
            throw new AciException(msgID, message);
        }
        String[] s = netmaskStr.split("\\.", -1);
        try {
            for(int i=0; i < IN4ADDRSZ; i++) {
                String quad=s[i].trim();
                long val=Integer.parseInt(quad);
                netmaskBytes[i] = (byte) (val & 0xff);
            }
        } catch (NumberFormatException nfex) {
            int id=MSGID_ACI_SYNTAX_IPV4_NOT_NUMERIC;
            String message = getMessage(id, expr);
            throw new AciException(id, message);
        }
        return netmaskBytes;
    }
    /**
     * Process the provided IPv4 address string parsed from the IP bind rule
     * address expression. It returns a byte array corresponding to the
     * address string.  The specified bit set represents wild-card characters
     * '*' found in the string.
     *
     * @param addrStr  A string representing an IPv4 address.
     * @param wildCardBitSet A bit set used to save wild-card information.
     * @param expr The original expression from the IP bind rule.
     * @return A address byte array that can be used along with the prefix bit
     *         mask to evaluate an IPv4 address.
     *
     * @throws AciException If the address string is not a valid IPv4 address
     *                      string.
     */
    private static byte[]
    procIPv4Addr(String addrStr, BitSet wildCardBitSet, String expr)
    throws AciException {
        byte[] addrBytes=new byte[IN4ADDRSZ];
        String[] s = addrStr.split("\\.", -1);
        try {
            if(s.length != IN4ADDRSZ) {
                int id=MSGID_ACI_SYNTAX_INVALID_IPV4_FORMAT;
                String message = getMessage(id, expr);
                throw new AciException(id, message);
            }
            for(int i=0; i < IN4ADDRSZ; i++) {
                String quad=s[i].trim();
                if(quad.equals("*"))
                    wildCardBitSet.set(i) ;
                else {
                    long val=Integer.parseInt(quad);
                    //must be between 0-255
                    if((val < 0) ||  (val > 0xff)) {
                        int id=MSGID_ACI_SYNTAX_INVALID_IPV4_VALUE;
                        String message = getMessage(id, expr);
                        throw new AciException(id, message);
                    }
                    addrBytes[i] = (byte) (val & 0xff);
                }
            }
        } catch (NumberFormatException nfex) {
            int id=MSGID_ACI_SYNTAX_IPV4_NOT_NUMERIC;
            String message = getMessage(id, expr);
            throw new AciException(id, message);
        }
        return addrBytes;
    }
    /**
     * Process the provided IPv6  address string parsed from the IP bind rule
     * IP expression. It returns a byte array corresponding to the
     * address string. Wild-cards are not allowed in IPv6 addresses.
     *
     * @param addrStr A string representing an IPv6 address.
     * @param expr The original expression from the IP bind rule.
     * @return A address byte array that can be used along with the prefix bit
     *         mask to evaluate an IPv6 address.
     * @throws AciException If the address string is not a valid IPv6 address
     *                      string.
     */
    private static byte[]
    procIPv6Addr(String addrStr, String expr) throws AciException {
        if(addrStr.indexOf('*') > -1) {
            int msgID=MSGID_ACI_SYNTAX_IPV6_WILDCARD_INVALID;
            String message = getMessage(msgID, expr);
            throw new AciException(msgID, message);
        }
        byte[] addrBytes;
        try {
            addrBytes=InetAddress.getByName(addrStr).getAddress();
        } catch (UnknownHostException ex) {
            int id=MSGID_ACI_SYNTAX_INVALID_IPV6_FORMAT;
            String message = getMessage(id, expr, ex.getMessage());
            throw new AciException(id, message);
        }
        return addrBytes;
    }
    /**
     * Evaluate the provided IP address against the information processed during
     * the IP bind rule expression decode.
     *
     * @param remoteAddr  A IP address to evaluate.
     * @return An enumeration representing the result of the evaluation.
     */
    public EnumEvalResult evaluate(InetAddress remoteAddr) {
        EnumEvalResult matched=EnumEvalResult.FALSE;
        IPType ipType=IPType.IPv4;
        byte[] addressBytes=remoteAddr.getAddress();
        if(remoteAddr instanceof Inet6Address) {
            ipType=IPType.IPv6;
            Inet6Address addr6 = (Inet6Address) remoteAddr;
            addressBytes= addr6.getAddress();
            if(addr6.isIPv4CompatibleAddress())
                ipType=IPType.IPv4;
        }
        if(ipType != this.ipType)
            return EnumEvalResult.FALSE;
        if(matchAddress(addressBytes))
            matched=EnumEvalResult.TRUE;
        return matched;
    }
    /**
     * Attempt to match the address byte array  using the  prefix bit mask array
     * and the address byte array processed in the decode. Wild-cards take
     * priority over the mask.
     *
     * @param addrBytes IP address byte array.
     * @return True if the remote address matches based on the information
     *         parsed from the IP bind rule expression.
     */
    private boolean matchAddress(byte[] addrBytes) {
        if(wildCardBitSet.cardinality() == IN4ADDRSZ)
            return true;
        for(int i=0;i <rulePrefixBytes.length; i++) {
            if(!wildCardBitSet.get(i)) {
                if((ruleAddrBytes[i] & rulePrefixBytes[i]) !=
                        (addrBytes[i] & rulePrefixBytes[i]))
                    return false;
            }
        }
        return true;
    }
}
opends/tests/functional-tests/shared/java/addAnEntry.java
@@ -1,4 +1,30 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
/*
 * Copyright (c) 1998. Sun Microsystems, Inc. All Rights Reserved.
 *
 * "@(#)addAnewEntry.java   1.2 98/04/22 SMI"
opends/tests/functional-tests/shared/java/modifyAnAttribute.java
@@ -19,7 +19,10 @@
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/IPTestCase.java
@@ -1,386 +1,386 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.authorization.dseecompat;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import java.net.InetAddress;
/**
 * Test of IP bind rule address decoding and address matching.
 */
public class IPTestCase extends AciTestCase {
    //Various patterns and addresses that can be put in IP bind rule
    //expressions. For example: ip="72.*.78.*,*.*.*.*".
    private String ipExpr="72.56.78.9,127.0.0.1";
    private String ipExprWc="72.*.78.*,*.*.*.*";
    private String netmaskWc=
             "72.56.78.0+255.255.255.240,127.0.0.0+255.255.255.0";
    private String netmaskWcOverRide=
                   "72.*.78.*+255.255.255.248,*.0.0.0+192.0.0.0";
    private String ip6Expr="12AB:0000:0000:CD30:0000:0000:0000:0000";
    private String ip6ExprC="12ab:0:0:cd30::";
    private String ip6ExprCidr="12ab:0:0:cd30::/60";
    private String ip6ExprCidrB="[12ab:0:0:cd30::]/60";
    private String ip4compat="::ffff:127.0.0.1,::ffff:72.56.78.9";
    private String cidr=
             "72.56.78.0/28,127.0.0.0/24";
    private String cidrWc=
                   "72.*.78.*/29,*.0.0.0/7";
    private String
            mixed="::ffff:72.56.78.9,45.*.33.*,[12ab:0:0:cd30::]/60," +
                 "56.56.78.0+255.255.255.0";
    //Providers that test the above expressions.
    //Mix of Ipv6 and Ipv4 addresses.
    @DataProvider(name = "mixedMatches")
    public Object[][] mixedData() {
        return new Object[][] {
                {"12AB:0000:0000:CD30:0000:0000:0000:0000"},
                {"12ab:0:0:cd3f:0000:0000:23DC:DC30"},
                {"45.56.33.9"},
                {"72.56.78.9"},
                {"56.56.78.9"}
        };
    }
    //Ipv6 addresses in long and various compressed forms.
    @DataProvider(name = "v6Matches")
    public Object[][] v6MatchData() {
        return new Object[][] {
                {"12AB:0000:0000:CD30:0000:0000:0000:0000"},
                {"12AB::CD30:0:0:0:0"},
                {"12ab:0:0:cd30::"}
        };
    }
    //Ipv6 addresses used in cidr tests.
    @DataProvider(name = "v6Matches1")
    public Object[][] v6MatchData1() {
        return new Object[][] {
                {"12ab:0:0:cd3f:0000:0000:23DC:DC30"},
                {"12ab::cd3f:0:0:23dc:dc30"}
        };
    }
    //Ipv4 addresses.
    @DataProvider(name = "v4Matches")
    public Object[][] v4MatchData() {
        return new Object[][] {
                {"127.0.0.1"},
                {"72.56.78.9"}
        };
    }
    //Valid IPv4 expressions.
    @DataProvider(name = "validRules")
    public Object[][] validData() {
        return new Object[][] {
            { "129.34.55.67/0"},
            { "129.*.78.55+255.255.248.0"},
            {"128.*.*.*"},
            {"129.45.23.67/22"},
            {"128.33.23.*/32"},
            {"*.*.*.*"},
            {"129.45.67.34/0"},
            {"129.45.67.34+255.255.255.0"}
        };
    }
    //Valid IPv6 expressions.
    @DataProvider(name = "valid6Rules")
    public Object[][] valid6Data() {
        return new Object[][] {
                {"2001:fecd:ba23:cd1f:dcb1:1010:9234:4088/124"},
                {"2001:fecd:ba23:cd1f:dcb1:1010:9234:4088"},
                {"[2001:fecd:ba23:cd1f:dcb1:1010:9234:4088]/45"},
                {"::/128"},
                {"::1/128"},
                {"::"},
                {"0:0:0:0:0:ffff:101.45.75.219"},
                {"1080::8:800:200C:417A"},
                {"0:0:0:0:0:0:101.45.75.219"},
                {"::101.45.75.219"}
        };
    }
    //Invalid Ipv4 expressions.
    @DataProvider(name = "invalidRules")
    public Object[][] inValidData() {
        return new Object[][] {
                {"128.33.23.xx"},
                {"128.33.23.22++"},
                {"128.33.23.22+"},
                {"128.33.23.22+56"},
                {"128.33.23.22+255.255.45"},
                {"128.33.23.22+255.255.45.45"},//netmask is invalid
                {"128.33.23.22/-1"},
                {"128..33.23"},
                {"128.33.23.66.88"},
                {"128.33.600.66"},
                {"128.33.9.66/33"},
                {"."},
                {"foo"}
        };
    }
    //Invalid IPv6 expressions.
    @DataProvider(name = "invalid6Rules")
    public Object[][] inValid5Data() {
        return new Object[][] {
                {"2001:feca:ba23:cd1f:dcb1:1010:9234:4088///124"},
                {"2001:feca:ba23:cd1f:dcb1:1010:9234:4088?124"},
                {"2001:fecz:ba23:cd1f:dcb1:1010:9234:4088/124"},
                {"2001:fecd:ba23:cd1ff:dcb1:1010:9234:4088/46"},
                {"0:0:0:0:0:ffff:101..45.75.219"},
                {"0:0:0:0:0:0:101.45.75.700"},
                {"1080::8:800:200C:417A/500"},
                {"1080::8:800:*:417A/66"},
        };
    }
    /**
     * This test uses the mixed (ipv4 and 6) expression above to match against
     * ipv4 and 6 addresses. All addresses should pass.
     *
     * @param ipStr The string to convert into InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider="mixedMatches")
    public void testMixed(String ipStr) throws Exception {
         IP ip=(IP) IP.decode(mixed, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
         InetAddress addr=InetAddress.getByName(ipStr);
         EnumEvalResult res=ip.evaluate(addr);
         if(res != EnumEvalResult.TRUE)
             throw new RuntimeException ("Addr: " + ipStr +
                     "expr: " + mixed);
     }
    /**
     * Test Ipv6 Ipv4 compat expression. All addresses should pass.
     *
     * @param ipStr The string to convert into IPv4 InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v4Matches")
    public void test4compat(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(ip4compat, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                    "expr: " + ip4compat);
    }
    /**
     * Test various IPv6 expressions. First IPv6 expression with CIDR prefix,
     * then RFC 2732 format (brackets around address) expression.
     *
     * @param ipStr The string to convert into IPv6 InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v6Matches1")
    public void test6Cidr(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(ip6ExprCidr, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + ip6ExprCidr);
        IP ip1=(IP) IP.decode(ip6ExprCidrB, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        EnumEvalResult res1=ip1.evaluate(addr);
        if(res1 != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + ip6ExprCidrB);
    }
    /**
     * Test IPv6 address expressions. First using the long form, then the
     * compressed form. The addresses to match have long and compressed forms
     * also. All tests should pass.
     *
     * @param ipStr The string to convert into IPv6 InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v6Matches")
    public void test6Simple(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(ip6Expr, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + ip6Expr);
        IP ip1=(IP) IP.decode(ip6ExprC, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        EnumEvalResult res1=ip1.evaluate(addr);
        if(res1 != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + ip6ExprC);
    }
    /**
     * Test IPv4 cidr prefix expressions and cidr prefix with wild-card
     * expressions. All tests should pass.
     *
     * @param ipStr The string to convert into IPv4 InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v4Matches")
    public void test4NCidr(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(cidr, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + cidr);
        IP ip1=(IP) IP.decode(cidrWc, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        EnumEvalResult res1=ip.evaluate(addr);
        if(res1 != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + cidrWc);
    }
    /**
     * Test IPv4 netmask expressions and netmask with wild-card expressions.
     * All tests should pass.
     *
     * @param ipStr The string to convert into IPv4 InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v4Matches")
    public void test4Netmasks(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(netmaskWc, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + netmaskWc);
        IP ip1 = (IP) IP.decode(netmaskWcOverRide,
                EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        EnumEvalResult res1=ip1.evaluate(addr);
        if(res1 != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + netmaskWc);
    }
    /**
     * Test IPv4 expressions and expression with wild-cards.
     * All Tests should pass.
     *
     * @param ipStr The string to convert into IPv4 InetAddress.
     * @throws Exception  If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v4Matches")
    public void test4SimpleWildCard(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(ipExpr, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + ipExpr);
        IP ipWc=(IP) IP.decode(ipExprWc, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        EnumEvalResult resWc=ipWc.evaluate(addr);
        if(resWc != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr:" + ipExprWc);
    }
    /**
     * Test  decoding of various valid rules.
     *
     * @param mask The expression to decode.
     * @throws Exception If the valid rule failed decoding.
     */
    @Test(dataProvider = "validRules")
    public void testValidIPDecode(String mask)
            throws Exception {
         IP.decode(mask, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
    }
    /**
     * Test decoding of invalid rules.
     *
     * @param mask The expression to decode.
     * @throws Exception If the valid rule failed decoding.
     */
    @Test(expectedExceptions= AciException.class, dataProvider="invalidRules")
    public void testInvalidDecode(String mask)
            throws Exception {
        try {
            IP.decode(mask, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        } catch (AciException ae) {
            throw ae;
        } catch (Exception e) {
            System.out.println(
                    "Invalid mask  <" + mask + "> threw wrong exception type.");
            throw e;
        }
        throw new RuntimeException(
                "Invalid mask <" + mask + "> did not throw an exception.");
    }
    /**
     * Test decoding of valid IPv6 rules.
     *
     * @param mask  The expression to decode.
     * @throws Exception If the valid rule failed decoding.
     */
    @Test(dataProvider = "valid6Rules")
    public void testValidIP6Decode(String mask)
            throws Exception {
        IP.decode(mask, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
    }
    /**
     * Test deocding of invalid IPV6 rules.
     *
     * @param mask The expression to decode.
     * @throws Exception If the valid rule failed decoding.
     */
    @Test(expectedExceptions= AciException.class, dataProvider="invalid6Rules")
    public void testInvalid6Decode(String mask)
            throws Exception {
        try {
            IP.decode(mask, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        } catch (AciException ae) {
            throw ae;
        } catch (Exception e) {
            System.out.println(
                    "Invalid mask  <" + mask + "> threw wrong exception type.");
            throw e;
        }
        throw new RuntimeException(
                "Invalid mask <" + mask + "> did not throw an exception.");
    }
}
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.authorization.dseecompat;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import java.net.InetAddress;
/**
 * Test of IP bind rule address decoding and address matching.
 */
public class IPTestCase extends AciTestCase {
    //Various patterns and addresses that can be put in IP bind rule
    //expressions. For example: ip="72.*.78.*,*.*.*.*".
    private String ipExpr="72.56.78.9,127.0.0.1";
    private String ipExprWc="72.*.78.*,*.*.*.*";
    private String netmaskWc=
             "72.56.78.0+255.255.255.240,127.0.0.0+255.255.255.0";
    private String netmaskWcOverRide=
                   "72.*.78.*+255.255.255.248,*.0.0.0+192.0.0.0";
    private String ip6Expr="12AB:0000:0000:CD30:0000:0000:0000:0000";
    private String ip6ExprC="12ab:0:0:cd30::";
    private String ip6ExprCidr="12ab:0:0:cd30::/60";
    private String ip6ExprCidrB="[12ab:0:0:cd30::]/60";
    private String ip4compat="::ffff:127.0.0.1,::ffff:72.56.78.9";
    private String cidr=
             "72.56.78.0/28,127.0.0.0/24";
    private String cidrWc=
                   "72.*.78.*/29,*.0.0.0/7";
    private String
            mixed="::ffff:72.56.78.9,45.*.33.*,[12ab:0:0:cd30::]/60," +
                 "56.56.78.0+255.255.255.0";
    //Providers that test the above expressions.
    //Mix of Ipv6 and Ipv4 addresses.
    @DataProvider(name = "mixedMatches")
    public Object[][] mixedData() {
        return new Object[][] {
                {"12AB:0000:0000:CD30:0000:0000:0000:0000"},
                {"12ab:0:0:cd3f:0000:0000:23DC:DC30"},
                {"45.56.33.9"},
                {"72.56.78.9"},
                {"56.56.78.9"}
        };
    }
    //Ipv6 addresses in long and various compressed forms.
    @DataProvider(name = "v6Matches")
    public Object[][] v6MatchData() {
        return new Object[][] {
                {"12AB:0000:0000:CD30:0000:0000:0000:0000"},
                {"12AB::CD30:0:0:0:0"},
                {"12ab:0:0:cd30::"}
        };
    }
    //Ipv6 addresses used in cidr tests.
    @DataProvider(name = "v6Matches1")
    public Object[][] v6MatchData1() {
        return new Object[][] {
                {"12ab:0:0:cd3f:0000:0000:23DC:DC30"},
                {"12ab::cd3f:0:0:23dc:dc30"}
        };
    }
    //Ipv4 addresses.
    @DataProvider(name = "v4Matches")
    public Object[][] v4MatchData() {
        return new Object[][] {
                {"127.0.0.1"},
                {"72.56.78.9"}
        };
    }
    //Valid IPv4 expressions.
    @DataProvider(name = "validRules")
    public Object[][] validData() {
        return new Object[][] {
            { "129.34.55.67/0"},
            { "129.*.78.55+255.255.248.0"},
            {"128.*.*.*"},
            {"129.45.23.67/22"},
            {"128.33.23.*/32"},
            {"*.*.*.*"},
            {"129.45.67.34/0"},
            {"129.45.67.34+255.255.255.0"}
        };
    }
    //Valid IPv6 expressions.
    @DataProvider(name = "valid6Rules")
    public Object[][] valid6Data() {
        return new Object[][] {
                {"2001:fecd:ba23:cd1f:dcb1:1010:9234:4088/124"},
                {"2001:fecd:ba23:cd1f:dcb1:1010:9234:4088"},
                {"[2001:fecd:ba23:cd1f:dcb1:1010:9234:4088]/45"},
                {"::/128"},
                {"::1/128"},
                {"::"},
                {"0:0:0:0:0:ffff:101.45.75.219"},
                {"1080::8:800:200C:417A"},
                {"0:0:0:0:0:0:101.45.75.219"},
                {"::101.45.75.219"}
        };
    }
    //Invalid Ipv4 expressions.
    @DataProvider(name = "invalidRules")
    public Object[][] inValidData() {
        return new Object[][] {
                {"128.33.23.xx"},
                {"128.33.23.22++"},
                {"128.33.23.22+"},
                {"128.33.23.22+56"},
                {"128.33.23.22+255.255.45"},
                {"128.33.23.22+255.255.45.45"},//netmask is invalid
                {"128.33.23.22/-1"},
                {"128..33.23"},
                {"128.33.23.66.88"},
                {"128.33.600.66"},
                {"128.33.9.66/33"},
                {"."},
                {"foo"}
        };
    }
    //Invalid IPv6 expressions.
    @DataProvider(name = "invalid6Rules")
    public Object[][] inValid5Data() {
        return new Object[][] {
                {"2001:feca:ba23:cd1f:dcb1:1010:9234:4088///124"},
                {"2001:feca:ba23:cd1f:dcb1:1010:9234:4088?124"},
                {"2001:fecz:ba23:cd1f:dcb1:1010:9234:4088/124"},
                {"2001:fecd:ba23:cd1ff:dcb1:1010:9234:4088/46"},
                {"0:0:0:0:0:ffff:101..45.75.219"},
                {"0:0:0:0:0:0:101.45.75.700"},
                {"1080::8:800:200C:417A/500"},
                {"1080::8:800:*:417A/66"},
        };
    }
    /**
     * This test uses the mixed (ipv4 and 6) expression above to match against
     * ipv4 and 6 addresses. All addresses should pass.
     *
     * @param ipStr The string to convert into InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider="mixedMatches")
    public void testMixed(String ipStr) throws Exception {
         IP ip=(IP) IP.decode(mixed, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
         InetAddress addr=InetAddress.getByName(ipStr);
         EnumEvalResult res=ip.evaluate(addr);
         if(res != EnumEvalResult.TRUE)
             throw new RuntimeException ("Addr: " + ipStr +
                     "expr: " + mixed);
     }
    /**
     * Test Ipv6 Ipv4 compat expression. All addresses should pass.
     *
     * @param ipStr The string to convert into IPv4 InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v4Matches")
    public void test4compat(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(ip4compat, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                    "expr: " + ip4compat);
    }
    /**
     * Test various IPv6 expressions. First IPv6 expression with CIDR prefix,
     * then RFC 2732 format (brackets around address) expression.
     *
     * @param ipStr The string to convert into IPv6 InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v6Matches1")
    public void test6Cidr(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(ip6ExprCidr, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + ip6ExprCidr);
        IP ip1=(IP) IP.decode(ip6ExprCidrB, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        EnumEvalResult res1=ip1.evaluate(addr);
        if(res1 != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + ip6ExprCidrB);
    }
    /**
     * Test IPv6 address expressions. First using the long form, then the
     * compressed form. The addresses to match have long and compressed forms
     * also. All tests should pass.
     *
     * @param ipStr The string to convert into IPv6 InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v6Matches")
    public void test6Simple(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(ip6Expr, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + ip6Expr);
        IP ip1=(IP) IP.decode(ip6ExprC, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        EnumEvalResult res1=ip1.evaluate(addr);
        if(res1 != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + ip6ExprC);
    }
    /**
     * Test IPv4 cidr prefix expressions and cidr prefix with wild-card
     * expressions. All tests should pass.
     *
     * @param ipStr The string to convert into IPv4 InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v4Matches")
    public void test4NCidr(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(cidr, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + cidr);
        IP ip1=(IP) IP.decode(cidrWc, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        EnumEvalResult res1=ip.evaluate(addr);
        if(res1 != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + cidrWc);
    }
    /**
     * Test IPv4 netmask expressions and netmask with wild-card expressions.
     * All tests should pass.
     *
     * @param ipStr The string to convert into IPv4 InetAddress.
     * @throws Exception If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v4Matches")
    public void test4Netmasks(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(netmaskWc, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + netmaskWc);
        IP ip1 = (IP) IP.decode(netmaskWcOverRide,
                EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        EnumEvalResult res1=ip1.evaluate(addr);
        if(res1 != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + netmaskWc);
    }
    /**
     * Test IPv4 expressions and expression with wild-cards.
     * All Tests should pass.
     *
     * @param ipStr The string to convert into IPv4 InetAddress.
     * @throws Exception  If the evaluation doesn't return true.
     */
    @Test(dataProvider = "v4Matches")
    public void test4SimpleWildCard(String ipStr) throws Exception {
        IP ip=(IP) IP.decode(ipExpr, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        InetAddress addr=InetAddress.getByName(ipStr);
        EnumEvalResult res=ip.evaluate(addr);
        if(res != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr: " + ipExpr);
        IP ipWc=(IP) IP.decode(ipExprWc, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        EnumEvalResult resWc=ipWc.evaluate(addr);
        if(resWc != EnumEvalResult.TRUE)
            throw new RuntimeException ("Addr: " + ipStr +
                                        "expr:" + ipExprWc);
    }
    /**
     * Test  decoding of various valid rules.
     *
     * @param mask The expression to decode.
     * @throws Exception If the valid rule failed decoding.
     */
    @Test(dataProvider = "validRules")
    public void testValidIPDecode(String mask)
            throws Exception {
         IP.decode(mask, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
    }
    /**
     * Test decoding of invalid rules.
     *
     * @param mask The expression to decode.
     * @throws Exception If the valid rule failed decoding.
     */
    @Test(expectedExceptions= AciException.class, dataProvider="invalidRules")
    public void testInvalidDecode(String mask)
            throws Exception {
        try {
            IP.decode(mask, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        } catch (AciException ae) {
            throw ae;
        } catch (Exception e) {
            System.out.println(
                    "Invalid mask  <" + mask + "> threw wrong exception type.");
            throw e;
        }
        throw new RuntimeException(
                "Invalid mask <" + mask + "> did not throw an exception.");
    }
    /**
     * Test decoding of valid IPv6 rules.
     *
     * @param mask  The expression to decode.
     * @throws Exception If the valid rule failed decoding.
     */
    @Test(dataProvider = "valid6Rules")
    public void testValidIP6Decode(String mask)
            throws Exception {
        IP.decode(mask, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
    }
    /**
     * Test deocding of invalid IPV6 rules.
     *
     * @param mask The expression to decode.
     * @throws Exception If the valid rule failed decoding.
     */
    @Test(expectedExceptions= AciException.class, dataProvider="invalid6Rules")
    public void testInvalid6Decode(String mask)
            throws Exception {
        try {
            IP.decode(mask, EnumBindRuleType.EQUAL_BINDRULE_TYPE);
        } catch (AciException ae) {
            throw ae;
        } catch (Exception e) {
            System.out.println(
                    "Invalid mask  <" + mask + "> threw wrong exception type.");
            throw e;
        }
        throw new RuntimeException(
                "Invalid mask <" + mask + "> did not throw an exception.");
    }
}