1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.james.jspf.core;
21
22 import java.util.ArrayList;
23 import java.util.StringTokenizer;
24
25
26
27
28
29
30
31
32 public class Inet6Util {
33
34 private Inet6Util() {
35
36 }
37
38
39
40
41
42 public static byte[] createByteArrayFromIPAddressString(
43 String ipAddressString) {
44
45 if (isValidIPV4Address(ipAddressString)) {
46 StringTokenizer tokenizer = new StringTokenizer(ipAddressString,
47 ".");
48 String token = "";
49 int tempInt = 0;
50 byte[] byteAddress = new byte[4];
51 for (int i = 0; i < 4; i++) {
52 token = tokenizer.nextToken();
53 tempInt = Integer.parseInt(token);
54 byteAddress[i] = (byte) tempInt;
55 }
56
57 return byteAddress;
58 }
59
60 if (ipAddressString.charAt(0) == '[') {
61 ipAddressString = ipAddressString.substring(1, ipAddressString
62 .length() - 1);
63 }
64
65 StringTokenizer tokenizer = new StringTokenizer(ipAddressString, ":.",
66 true);
67 ArrayList hexStrings = new ArrayList();
68 ArrayList decStrings = new ArrayList();
69 String token = "";
70 String prevToken = "";
71 int doubleColonIndex = -1;
72
73
74
75
76
77
78
79 while (tokenizer.hasMoreTokens()) {
80 prevToken = token;
81 token = tokenizer.nextToken();
82
83 if (token.equals(":")) {
84 if (prevToken.equals(":")) {
85 doubleColonIndex = hexStrings.size();
86 } else if (!prevToken.equals("")) {
87 hexStrings.add(prevToken);
88 }
89 } else if (token.equals(".")) {
90 decStrings.add(prevToken);
91 }
92 }
93
94 if (prevToken.equals(":")) {
95 if (token.equals(":")) {
96 doubleColonIndex = hexStrings.size();
97 } else {
98 hexStrings.add(token);
99 }
100 } else if (prevToken.equals(".")) {
101 decStrings.add(token);
102 }
103
104
105
106 int hexStringsLength = 8;
107
108
109
110 if (decStrings.size() > 0) {
111 hexStringsLength -= 2;
112 }
113
114
115 if (doubleColonIndex != -1) {
116 int numberToInsert = hexStringsLength - hexStrings.size();
117 for (int i = 0; i < numberToInsert; i++) {
118 hexStrings.add(doubleColonIndex, "0");
119 }
120 }
121
122 byte ipByteArray[] = new byte[16];
123
124
125 for (int i = 0; i < hexStrings.size(); i++) {
126 convertToBytes((String) hexStrings.get(i), ipByteArray, i * 2);
127 }
128
129
130 for (int i = 0; i < decStrings.size(); i++) {
131 ipByteArray[i + 12] = (byte) (Integer.parseInt((String) decStrings
132 .get(i)) & 255);
133 }
134
135
136
137 boolean ipV4 = true;
138 for (int i = 0; i < 10; i++) {
139 if (ipByteArray[i] != 0) {
140 ipV4 = false;
141 break;
142 }
143 }
144
145 if (ipByteArray[10] != -1 || ipByteArray[11] != -1) {
146 ipV4 = false;
147 }
148
149 if (ipV4) {
150 byte ipv4ByteArray[] = new byte[4];
151 for (int i = 0; i < 4; i++) {
152 ipv4ByteArray[i] = ipByteArray[i + 12];
153 }
154 return ipv4ByteArray;
155 }
156
157 return ipByteArray;
158
159 }
160
161
162 public static void convertToBytes(String hexWord, byte ipByteArray[],
163 int byteIndex) {
164
165 int hexWordLength = hexWord.length();
166 int hexWordIndex = 0;
167 ipByteArray[byteIndex] = 0;
168 ipByteArray[byteIndex + 1] = 0;
169 int charValue;
170
171
172 if (hexWordLength > 3) {
173 charValue = getIntValue(hexWord.charAt(hexWordIndex++));
174 ipByteArray[byteIndex] = (byte) (ipByteArray[byteIndex] | (charValue << 4));
175 }
176
177
178 if (hexWordLength > 2) {
179 charValue = getIntValue(hexWord.charAt(hexWordIndex++));
180 ipByteArray[byteIndex] = (byte) (ipByteArray[byteIndex] | charValue);
181 }
182
183
184 if (hexWordLength > 1) {
185 charValue = getIntValue(hexWord.charAt(hexWordIndex++));
186 ipByteArray[byteIndex + 1] = (byte) (ipByteArray[byteIndex + 1] | (charValue << 4));
187 }
188
189
190 charValue = getIntValue(hexWord.charAt(hexWordIndex));
191 ipByteArray[byteIndex + 1] = (byte) (ipByteArray[byteIndex + 1] | charValue & 15);
192 }
193
194 static int getIntValue(char c) {
195
196 switch (c) {
197 case '0':
198 return 0;
199 case '1':
200 return 1;
201 case '2':
202 return 2;
203 case '3':
204 return 3;
205 case '4':
206 return 4;
207 case '5':
208 return 5;
209 case '6':
210 return 6;
211 case '7':
212 return 7;
213 case '8':
214 return 8;
215 case '9':
216 return 9;
217 }
218
219 c = Character.toLowerCase(c);
220 switch (c) {
221 case 'a':
222 return 10;
223 case 'b':
224 return 11;
225 case 'c':
226 return 12;
227 case 'd':
228 return 13;
229 case 'e':
230 return 14;
231 case 'f':
232 return 15;
233 }
234 return 0;
235 }
236
237 public static boolean isValidIP6Address(String ipAddress) {
238 int length = ipAddress.length();
239 boolean doubleColon = false;
240 int numberOfColons = 0;
241 int numberOfPeriods = 0;
242 int numberOfPercent = 0;
243 String word = "";
244 char c = 0;
245 char prevChar = 0;
246 int offset = 0;
247
248 if (length < 2)
249 return false;
250
251 for (int i = 0; i < length; i++) {
252 prevChar = c;
253 c = ipAddress.charAt(i);
254 switch (c) {
255
256
257 case '[':
258 if (i != 0)
259 return false;
260 if (ipAddress.charAt(length - 1) != ']')
261 return false;
262 offset = 1;
263 if (length < 4)
264 return false;
265 break;
266
267
268 case ']':
269 if (i != length - 1)
270 return false;
271 if (ipAddress.charAt(0) != '[')
272 return false;
273 break;
274
275
276 case '.':
277 numberOfPeriods++;
278 if (numberOfPeriods > 3)
279 return false;
280 if (!isValidIP4Word(word))
281 return false;
282 if (numberOfColons != 6 && !doubleColon)
283 return false;
284
285
286 if (numberOfColons == 7 && ipAddress.charAt(0 + offset) != ':'
287 && ipAddress.charAt(1 + offset) != ':')
288 return false;
289 word = "";
290 break;
291
292 case ':':
293
294
295
296 if (i == offset && (ipAddress.length() <= i || ipAddress.charAt(i+1) != ':')) {
297 return false;
298 }
299
300 numberOfColons++;
301 if (numberOfColons > 7)
302 return false;
303 if (numberOfPeriods > 0)
304 return false;
305 if (prevChar == ':') {
306 if (doubleColon)
307 return false;
308 doubleColon = true;
309 }
310 word = "";
311 break;
312 case '%':
313 if (numberOfColons == 0)
314 return false;
315 numberOfPercent++;
316
317
318 if ((i + 1) >= length) {
319
320
321 return false;
322 }
323 try {
324 Integer.parseInt(ipAddress.substring(i + 1));
325 } catch (NumberFormatException e) {
326
327
328
329 return false;
330 }
331 break;
332
333 default:
334 if (numberOfPercent == 0) {
335 if (word.length() > 3)
336 return false;
337 if (!isValidHexChar(c))
338 return false;
339 }
340 word += c;
341 }
342 }
343
344
345 if (numberOfPeriods > 0) {
346 if (numberOfPeriods != 3 || !isValidIP4Word(word))
347 return false;
348 } else {
349
350
351 if (numberOfColons != 7 && !doubleColon) {
352 return false;
353 }
354
355
356
357
358 if (numberOfPercent == 0) {
359 if (word == "" && ipAddress.charAt(length - 1 - offset) == ':'
360 && ipAddress.charAt(length - 2 - offset) != ':') {
361 return false;
362 }
363 }
364 }
365
366 return true;
367 }
368
369 public static boolean isValidIP4Word(String word) {
370 char c;
371 if (word.length() < 1 || word.length() > 3)
372 return false;
373 for (int i = 0; i < word.length(); i++) {
374 c = word.charAt(i);
375 if (!(c >= '0' && c <= '9'))
376 return false;
377 }
378 if (Integer.parseInt(word) > 255)
379 return false;
380 return true;
381 }
382
383 static boolean isValidHexChar(char c) {
384
385 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')
386 || (c >= 'a' && c <= 'f');
387 }
388
389
390
391
392
393
394
395 public static boolean isValidIPV4Address(String value) {
396
397 int periods = 0;
398 int i = 0;
399 int length = value.length();
400
401 if (length > 15)
402 return false;
403 char c = 0;
404 String word = "";
405 for (i = 0; i < length; i++) {
406 c = value.charAt(i);
407 if (c == '.') {
408 periods++;
409 if (periods > 3)
410 return false;
411 if (word == "")
412 return false;
413 if (Integer.parseInt(word) > 255)
414 return false;
415 word = "";
416 } else if (!(Character.isDigit(c)))
417 return false;
418 else {
419 if (word.length() > 2)
420 return false;
421 word += c;
422 }
423 }
424
425 if (word == "" || Integer.parseInt(word) > 255)
426 return false;
427 if (periods != 3)
428 return false;
429 return true;
430 }
431
432 }