/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package freenet.io;
import java.util.regex.Pattern;
/**
* Identifies numeric IP addresses. This class is currently capable of
* recognizing:
* <ul>
* <li>IPv4 unabridged (a.b.c.d)</li>
* <li>IPv4 abridged (a.b.d or a.d)</li>
* <li>IPv6 unabridged (a:b:c:d:e:f:g:h)</li>
* </ul>
*
* @author David Roden <droden@gmail.com>
* @version $Id$
*/
public class AddressIdentifier {
public static final Pattern ipv4Pattern, ipv6Pattern, ipv6PatternWithPercentScopeID, ipv6ISATAPPattern;
static {
String byteRegex = "(?>2[0-4][0-9]|25[0-5]|[01]?[0-9]?[0-9]?)";
String ipv4AddressRegex = byteRegex + "\\.(?>" + byteRegex + "\\.)?(?>" + byteRegex + "\\.)?" + byteRegex;
ipv4Pattern = Pattern.compile(ipv4AddressRegex);
String wordRegex = "(?>[0-9a-fA-F]{1,4})";
String percentScopeIDRegex = "(?>%[0-9]{1,3})?";
String ipv6AddressRegex = wordRegex + "?:" + wordRegex + ':' + wordRegex + ':' + wordRegex + ':' + wordRegex + ':' + wordRegex + ':' + wordRegex + ':' + wordRegex;
String ipv6ISATAPAddressRegex = wordRegex + "?:" + wordRegex + ':' + wordRegex + ':' + wordRegex + ":(0){1,4}:5(efe|EFE):" + wordRegex + ':' + wordRegex + percentScopeIDRegex;
ipv6Pattern = Pattern.compile(ipv6AddressRegex);
ipv6PatternWithPercentScopeID = Pattern.compile(ipv6AddressRegex + percentScopeIDRegex);
ipv6ISATAPPattern = Pattern.compile(ipv6ISATAPAddressRegex);
}
public enum AddressType {
OTHER, IPv4, IPv6;
}
/**
* Tries to detemine the address type of the given address.
*
* REDFLAG: IPv6 percent scope ID's could cause problems with URI's.
* Should not be exploitable as we don't do anything important with
* URI's with hosts in anyway. In particular we MUST NOT do anything
* with hosts from URI's from untrusted sources e.g. content filter.
* But then that would be completely stupid, so we don't.
*
* @param address
* The address to determine the type of
* @return {@link AddressType#OTHER} if <code>address</code> is a
* hostname, {@link AddressType#IPv4} or {@link AddressType#IPv6}
* otherwise
*/
public static AddressType getAddressType(String address) {
return AddressIdentifier.getAddressType(address,true);
}
/**
* Tries to detemine the address type of the given address.
*
* @param address
* The address to determine the type of
* @param allowIPv6PercentScopeID
* If true, match %<scope-id> suffixed IPv6 IP addresses
* @return {@link AddressType#OTHER} if <code>address</code> is a
* hostname, {@link AddressType#IPv4} or {@link AddressType#IPv6}
* otherwise
*/
public static AddressType getAddressType(String address, boolean allowIPv6PercentScopeID) {
if (ipv4Pattern.matcher(address).matches()) {
return AddressType.IPv4;
}else if ((allowIPv6PercentScopeID ? ipv6PatternWithPercentScopeID : ipv6Pattern).matcher(address).matches()) {
return AddressType.IPv6;
}
return AddressType.OTHER;
}
/**
* @see <a href="http://www.ietf.org/rfc/rfc4214.txt">rfc4214</a>
*/
public static boolean isAnISATAPIPv6Address(String address) {
return ipv6ISATAPPattern.matcher(address).matches();
}
}