Skip to content

Commit 6b90487

Browse files
author
Federico Fissore
committed
Proxy PAC support: SubnetUtils is not IPv6 aware, using CIDRUtils to check if IP is in range
1 parent 7e15e9d commit 6b90487

File tree

2 files changed

+145
-2
lines changed

2 files changed

+145
-2
lines changed

arduino-core/src/cc/arduino/net/PACSupportMethods.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
package cc.arduino.net;
3131

32+
import edazdarevic.commons.net.CIDRUtils;
3233
import org.apache.commons.net.util.SubnetUtils;
3334

3435
import java.net.InetAddress;
@@ -62,10 +63,10 @@ public boolean isResolvable(String host) {
6263
}
6364
}
6465

65-
public boolean isInNet(String host, String pattern, String mask) {
66+
public boolean isInNet(String host, String pattern, String mask) throws UnknownHostException {
6667
SubnetUtils subnetUtils = new SubnetUtils(pattern, mask);
6768
subnetUtils.setInclusiveHostCount(true);
68-
return subnetUtils.getInfo().isInRange(host);
69+
return new CIDRUtils(subnetUtils.getInfo().getCidrSignature()).isInRange(host);
6970
}
7071

7172
public String dnsResolve(String host) throws UnknownHostException {
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2013 Edin Dazdarevic (edin.dazdarevic@gmail.com)
5+
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*
24+
* */
25+
26+
package edazdarevic.commons.net;
27+
28+
import java.math.BigInteger;
29+
import java.net.InetAddress;
30+
import java.net.UnknownHostException;
31+
import java.nio.ByteBuffer;
32+
import java.util.ArrayList;
33+
import java.util.List;
34+
35+
/**
36+
* A class that enables to get an IP range from CIDR specification. It supports
37+
* both IPv4 and IPv6.
38+
*/
39+
public class CIDRUtils {
40+
private final String cidr;
41+
42+
private InetAddress inetAddress;
43+
private InetAddress startAddress;
44+
private InetAddress endAddress;
45+
private final int prefixLength;
46+
47+
48+
public CIDRUtils(String cidr) throws UnknownHostException {
49+
50+
this.cidr = cidr;
51+
52+
/* split CIDR to address and prefix part */
53+
if (this.cidr.contains("/")) {
54+
int index = this.cidr.indexOf("/");
55+
String addressPart = this.cidr.substring(0, index);
56+
String networkPart = this.cidr.substring(index + 1);
57+
58+
inetAddress = InetAddress.getByName(addressPart);
59+
prefixLength = Integer.parseInt(networkPart);
60+
61+
calculate();
62+
} else {
63+
throw new IllegalArgumentException("not an valid CIDR format!");
64+
}
65+
}
66+
67+
68+
private void calculate() throws UnknownHostException {
69+
70+
ByteBuffer maskBuffer;
71+
int targetSize;
72+
if (inetAddress.getAddress().length == 4) {
73+
maskBuffer =
74+
ByteBuffer
75+
.allocate(4)
76+
.putInt(-1);
77+
targetSize = 4;
78+
} else {
79+
maskBuffer = ByteBuffer.allocate(16)
80+
.putLong(-1L)
81+
.putLong(-1L);
82+
targetSize = 16;
83+
}
84+
85+
BigInteger mask = (new BigInteger(1, maskBuffer.array())).not().shiftRight(prefixLength);
86+
87+
ByteBuffer buffer = ByteBuffer.wrap(inetAddress.getAddress());
88+
BigInteger ipVal = new BigInteger(1, buffer.array());
89+
90+
BigInteger startIp = ipVal.and(mask);
91+
BigInteger endIp = startIp.add(mask.not());
92+
93+
byte[] startIpArr = toBytes(startIp.toByteArray(), targetSize);
94+
byte[] endIpArr = toBytes(endIp.toByteArray(), targetSize);
95+
96+
this.startAddress = InetAddress.getByAddress(startIpArr);
97+
this.endAddress = InetAddress.getByAddress(endIpArr);
98+
99+
}
100+
101+
private byte[] toBytes(byte[] array, int targetSize) {
102+
int counter = 0;
103+
List<Byte> newArr = new ArrayList<Byte>();
104+
while (counter < targetSize && (array.length - 1 - counter >= 0)) {
105+
newArr.add(0, array[array.length - 1 - counter]);
106+
counter++;
107+
}
108+
109+
int size = newArr.size();
110+
for (int i = 0; i < (targetSize - size); i++) {
111+
112+
newArr.add(0, (byte) 0);
113+
}
114+
115+
byte[] ret = new byte[newArr.size()];
116+
for (int i = 0; i < newArr.size(); i++) {
117+
ret[i] = newArr.get(i);
118+
}
119+
return ret;
120+
}
121+
122+
public String getNetworkAddress() {
123+
124+
return this.startAddress.getHostAddress();
125+
}
126+
127+
public String getBroadcastAddress() {
128+
return this.endAddress.getHostAddress();
129+
}
130+
131+
public boolean isInRange(String ipAddress) throws UnknownHostException {
132+
InetAddress address = InetAddress.getByName(ipAddress);
133+
BigInteger start = new BigInteger(1, this.startAddress.getAddress());
134+
BigInteger end = new BigInteger(1, this.endAddress.getAddress());
135+
BigInteger target = new BigInteger(1, address.getAddress());
136+
137+
int st = start.compareTo(target);
138+
int te = target.compareTo(end);
139+
140+
return (st == -1 || st == 0) && (te == -1 || te == 0);
141+
}
142+
}

0 commit comments

Comments
 (0)