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