/* * This file is part of the Wayback archival access software * (http://archive-access.sourceforge.net/projects/wayback/). * * Licensed to the Internet Archive (IA) by one or more individual * contributors. * * The IA licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.archive.wayback.util; import java.util.regex.Matcher; import java.util.regex.Pattern; public class IPRange { // STATIC MEMBERS: private final static Pattern IP_PATTERN = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); private final static Pattern IP_MASK_PATTERN = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)/(\\d+)"); private final static byte[] FULL_MASK = {(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff}; private final static byte[] flags = { (byte) 0x80, (byte) 0x40, (byte) 0x20, (byte) 0x10, (byte) 0x08, (byte) 0x04, (byte) 0x02, (byte) 0x01, }; // INSTANCE MEMBERS: private byte[] ip = null; private byte[] mask = null; private String original = null; // INSTANCE METHODS: public byte[] getIp() { return ip; } public byte[] getMask() { return mask; } public boolean contains(String ipString) { byte[] testIP = matchIP(ipString); if(testIP == null) { return false; } return contains(testIP); } public boolean contains(byte[] testIP) { byte[] masked = and(testIP,mask); return equals(ip,masked); } public String getRangeString() { return null; } public void setRangeString(String range) { setRange(range); } public String getOriginal() { return original; } public boolean setRange(String range) { original = range; Matcher m = IP_MASK_PATTERN.matcher(range); if(m != null) { if(m.matches()) { return setRangeMask(m.group(1),m.group(2)); } } return setRangeIP(range); } // PRIVATE INSTANCE METHODS: private boolean setRangeMask(String ipString, String maskBitsString) { byte[] tmpMask = maskBits(maskBitsString); if(tmpMask != null) { if(setRangeIP(ipString)) { mask = tmpMask; ip = and(ip,mask); return true; } } return false; } private boolean setRangeIP(String ipString) { byte[] tmpIp = matchIP(ipString); if(tmpIp != null) { ip = tmpIp; mask = FULL_MASK; return true; } return false; } // STATIC METHODS: public static byte[] maskBits(String bitsString) { try { int bits = Integer.parseInt(bitsString); return maskBits(bits); } catch(NumberFormatException e) { e.printStackTrace(); } return null; } public static byte[] maskBits(int bits) { byte[] res = new byte[4]; if(bits < 0) { return null; } if(bits > 32) { return null; } for(int i=0; i < 4; i++) { int startBit = 8 * i; int endBit = 8 * (i+1); if(bits < startBit) { res[i] = (byte)0x00; } else if(bits >= endBit) { res[i] = (byte)0xff; } else { int numOn = bits - startBit; int val = 0x00; for(int j=0; j < numOn; j++) { val |= flags[j]; } res[i] = (byte) val; } } return res; } public static String bitString(byte b) { StringBuilder sb = new StringBuilder(8); for(int i=0; i<8; i++) { sb.append(((b & flags[i])==0)?"0":"1"); } return sb.toString(); } public static byte[] and(byte b1[], byte b2[]) { byte[] res = new byte[4]; for(int i=0; i<4; i++) { res[i] = (byte) ((byte) b1[i] & (byte) b2[i]); } return res; } public static boolean equals(byte b1[], byte b2[]) { for(int i=0; i<4; i++) { if(b1[i] != b2[i]) { return false; } } return true; } public static boolean isOn(byte b, int pos) { return (b & flags[pos]) != 0; } public static byte[] matchIP(String ip) { Matcher m = IP_PATTERN.matcher(ip); if(m != null) { if(m.matches()) { try { byte[] res = new byte[4]; for(int i=0; i < 4; i++) { int testInt = Integer.parseInt(m.group(i+1)); if(testInt < 0) { return null; } if(testInt > 255) { return null; } res[i] = (byte) testInt; } return res; } catch(NumberFormatException e) { e.printStackTrace(); return null; } } } return null; } }