/* * 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(); } }