1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.handler.ipfilter;
17
18 import java.net.Inet4Address;
19 import java.net.Inet6Address;
20 import java.net.InetAddress;
21 import java.net.UnknownHostException;
22 import java.util.StringTokenizer;
23
24
25
26 public abstract class CIDR implements Comparable<CIDR> {
27
28 protected InetAddress baseAddress;
29
30
31 protected int cidrMask;
32
33
34
35
36
37
38 public static CIDR newCIDR(InetAddress baseAddress, int cidrMask) throws UnknownHostException {
39 if (cidrMask < 0) {
40 throw new UnknownHostException("Invalid mask length used: " + cidrMask);
41 }
42 if (baseAddress instanceof Inet4Address) {
43 if (cidrMask > 32) {
44 throw new UnknownHostException("Invalid mask length used: " + cidrMask);
45 }
46 return new CIDR4((Inet4Address) baseAddress, cidrMask);
47 }
48
49 if (cidrMask > 128) {
50 throw new UnknownHostException("Invalid mask length used: " + cidrMask);
51 }
52 return new CIDR6((Inet6Address) baseAddress, cidrMask);
53 }
54
55
56
57
58
59
60 public static CIDR newCIDR(InetAddress baseAddress, String scidrMask) throws UnknownHostException {
61 int cidrMask = getNetMask(scidrMask);
62 if (cidrMask < 0) {
63 throw new UnknownHostException("Invalid mask length used: " + cidrMask);
64 }
65 if (baseAddress instanceof Inet4Address) {
66 if (cidrMask > 32) {
67 throw new UnknownHostException("Invalid mask length used: " + cidrMask);
68 }
69 return new CIDR4((Inet4Address) baseAddress, cidrMask);
70 }
71 cidrMask += 96;
72
73 if (cidrMask > 128) {
74 throw new UnknownHostException("Invalid mask length used: " + cidrMask);
75 }
76 return new CIDR6((Inet6Address) baseAddress, cidrMask);
77 }
78
79
80
81
82
83
84
85
86
87
88 public static CIDR newCIDR(String cidr) throws UnknownHostException {
89 int p = cidr.indexOf('/');
90 if (p < 0) {
91 throw new UnknownHostException("Invalid CIDR notation used: " + cidr);
92 }
93 String addrString = cidr.substring(0, p);
94 String maskString = cidr.substring(p + 1);
95 InetAddress addr = addressStringToInet(addrString);
96 int mask = 0;
97 if (maskString.indexOf('.') < 0) {
98 mask = parseInt(maskString, -1);
99 } else {
100 mask = getNetMask(maskString);
101 if (addr instanceof Inet6Address) {
102 mask += 96;
103 }
104 }
105 if (mask < 0) {
106 throw new UnknownHostException("Invalid mask length used: " + maskString);
107 }
108 return newCIDR(addr, mask);
109 }
110
111
112 public InetAddress getBaseAddress() {
113 return baseAddress;
114 }
115
116
117 public int getMask() {
118 return cidrMask;
119 }
120
121
122 @Override
123 public String toString() {
124 return baseAddress.getHostAddress() + '/' + cidrMask;
125 }
126
127
128 public abstract InetAddress getEndAddress();
129
130
131
132
133
134
135
136
137 public abstract boolean contains(InetAddress inetAddress);
138
139 @Override
140 public boolean equals(Object obj) {
141 if (!(obj instanceof CIDR)) {
142 return false;
143 }
144 return compareTo((CIDR) obj) == 0;
145 }
146
147 @Override
148 public int hashCode() {
149 return baseAddress.hashCode();
150 }
151
152
153
154
155
156
157
158 private static InetAddress addressStringToInet(String addr) throws UnknownHostException {
159 return InetAddress.getByName(addr);
160 }
161
162
163
164
165
166
167
168
169 private static int getNetMask(String netMask) {
170 StringTokenizer nm = new StringTokenizer(netMask, ".");
171 int i = 0;
172 int[] netmask = new int[4];
173 while (nm.hasMoreTokens()) {
174 netmask[i] = Integer.parseInt(nm.nextToken());
175 i++;
176 }
177 int mask1 = 0;
178 for (i = 0; i < 4; i++) {
179 mask1 += Integer.bitCount(netmask[i]);
180 }
181 return mask1;
182 }
183
184
185
186
187
188
189
190 private static int parseInt(String intstr, int def) {
191 Integer res;
192 if (intstr == null) {
193 return def;
194 }
195 try {
196 res = Integer.decode(intstr);
197 } catch (Exception e) {
198 res = def;
199 }
200 return res.intValue();
201 }
202
203
204
205
206
207
208
209 public static byte[] getIpV4FromIpV6(Inet6Address address) {
210 byte[] baddr = address.getAddress();
211 for (int i = 0; i < 9; i++) {
212 if (baddr[i] != 0) {
213 throw new IllegalArgumentException("This IPv6 address cannot be used in IPv4 context");
214 }
215 }
216 if (baddr[10] != 0 && baddr[10] != 0xFF || baddr[11] != 0 && baddr[11] != 0xFF) {
217 throw new IllegalArgumentException("This IPv6 address cannot be used in IPv4 context");
218 }
219 return new byte[]
220 {baddr[12], baddr[13], baddr[14], baddr[15]};
221 }
222
223
224
225
226
227
228
229 public static byte[] getIpV6FromIpV4(Inet4Address address) {
230 byte[] baddr = address.getAddress();
231 return new byte[]
232 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, baddr[0], baddr[1], baddr[2], baddr[3]};
233 }
234 }