summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/btr/proxy/selector/whitelist/IpRangeFilter.java
blob: 293f5209031535c7431c3b61a55bb944ecce942f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package com.btr.proxy.selector.whitelist;

import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;

import com.btr.proxy.util.UriFilter;

/*****************************************************************************
 * Filters an URI by inspecting it's IP address is in a given range. 
 * The range  as must be defined in CIDR notation.
 * e.g. 192.0.2.1/24,
 *
 * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
 ****************************************************************************/

public class IpRangeFilter implements UriFilter {

	private byte[] matchTo;
	int numOfBits;

	/*************************************************************************
	 * Constructor
	 * @param matchTo the match subnet in CIDR notation.
	 ************************************************************************/
	
	public IpRangeFilter(String matchTo) {
		super();
		
		String[] parts = matchTo.split("/");
		if (parts.length != 2) {
			throw new IllegalArgumentException("IP range is not valid:"+matchTo);
		}
		
		try {
			InetAddress address = InetAddress.getByName(parts[0].trim());
			this.matchTo = address.getAddress();
		} catch (UnknownHostException e) {
			throw new IllegalArgumentException("IP range is not valid:"+matchTo);
		}
		
		this.numOfBits = Integer.parseInt(parts[1].trim());
	}
	
	/*************************************************************************
	 * accept
	 * @see com.btr.proxy.util.UriFilter#accept(java.net.URI)
	 ************************************************************************/

	public boolean accept(URI uri) {
		if (uri == null || uri.getHost() == null) {
			return false;
		}
		try {
			InetAddress address = InetAddress.getByName(uri.getHost());
			byte[] addr = address.getAddress();
			
			// Comparing IP6 against IP4?
			if (addr.length != this.matchTo.length) {
				return false;
			}

			int bit = 0;
			for (int nibble = 0; nibble < addr.length; nibble++) {
				for (int nibblePos = 7; nibblePos >= 0; nibblePos--) {
					int mask = 1 << nibblePos;
					if ((this.matchTo[nibble] & mask) != (addr[nibble] & mask)) {
						return false;
					}
					bit++;
					if (bit >= this.numOfBits) {
						return true;
					}
				}
			}
			
		} catch (UnknownHostException e) {
			// In this case we can not get the IP do not match.
		}
		return false;
	}

}