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 package org.apache.hc.core5.net;
29
30 import java.net.InetAddress;
31 import java.net.InetSocketAddress;
32 import java.net.SocketAddress;
33 import java.net.UnknownHostException;
34 import java.util.regex.Pattern;
35
36 import org.apache.hc.core5.util.Args;
37
38
39
40
41
42
43 public class InetAddressUtils {
44
45
46
47
48
49
50 public static final byte IPV4 = 1;
51
52
53
54
55
56 public static final byte IPV6 = 4;
57
58 private InetAddressUtils() {
59 }
60
61 private static final String IPV4_BASIC_PATTERN_STRING =
62 "(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){1}" +
63 "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){2}" +
64 "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])";
65
66 private static final Pattern IPV4_PATTERN =
67 Pattern.compile("^" + IPV4_BASIC_PATTERN_STRING + "$");
68
69 private static final Pattern IPV4_MAPPED_IPV6_PATTERN =
70 Pattern.compile("^::[fF]{4}:" + IPV4_BASIC_PATTERN_STRING + "$");
71
72 private static final Pattern IPV6_STD_PATTERN =
73 Pattern.compile(
74 "^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}$");
75
76 private static final Pattern IPV6_HEX_COMPRESSED_PATTERN =
77 Pattern.compile(
78 "^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)" +
79 "::" +
80 "(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)$");
81
82
83
84
85
86 private static final Pattern SCOPE_ID_PATTERN = Pattern.compile("^[a-zA-Z0-9\\-]+$");
87
88
89
90
91 private static final char SCOPE_ID_DELIMITER = '%';
92
93
94
95
96
97
98 private static final char COLON_CHAR = ':';
99
100
101 private static final int MAX_COLON_COUNT = 7;
102
103
104
105
106 @Deprecated
107 public static boolean isIPv4Address(final String input) {
108 return isIPv4(input);
109 }
110
111
112
113
114
115
116
117
118 public static boolean isIPv4(final CharSequence input) {
119 return IPV4_PATTERN.matcher(input).matches();
120 }
121
122
123
124
125 @Deprecated
126 public static boolean isIPv4MappedIPv64Address(final String input) {
127 return isIPv4MappedIPv6(input);
128 }
129
130
131
132
133
134
135
136
137 public static boolean isIPv4MappedIPv6(final CharSequence input) {
138 return IPV4_MAPPED_IPV6_PATTERN.matcher(input).matches();
139 }
140
141 static boolean hasValidIPv6ColonCount(final CharSequence input) {
142 int colonCount = 0;
143 for (int i = 0; i < input.length(); i++) {
144 if (input.charAt(i) == COLON_CHAR) {
145 colonCount++;
146 }
147 }
148
149 return colonCount >= 2 && colonCount <= MAX_COLON_COUNT;
150 }
151
152
153
154
155 @Deprecated
156 public static boolean isIPv6StdAddress(final String input) {
157 return isIPv6Std(input);
158 }
159
160
161
162
163
164
165
166
167 public static boolean isIPv6Std(final CharSequence input) {
168 return hasValidIPv6ColonCount(input) && IPV6_STD_PATTERN.matcher(input).matches();
169 }
170
171
172
173
174 @Deprecated
175 public static boolean isIPv6HexCompressedAddress(final String input) {
176 return isIPv6HexCompressed(input);
177 }
178
179
180
181
182
183
184
185
186 public static boolean isIPv6HexCompressed(final CharSequence input) {
187 return hasValidIPv6ColonCount(input) && IPV6_HEX_COMPRESSED_PATTERN.matcher(input).matches();
188 }
189
190
191
192
193 @Deprecated
194 public static boolean isIPv6Address(final String input) {
195 return isIPv6(input);
196 }
197
198
199
200
201
202
203
204
205 public static boolean isIPv6(final CharSequence input) {
206 int index = -1;
207 for (int i = 0; i < input.length(); i++) {
208 if (input.charAt(i) == SCOPE_ID_DELIMITER) {
209 index = i;
210 break;
211 }
212 }
213 if (index == -1) {
214 return isIPv6Std(input) || isIPv6HexCompressed(input);
215 } else {
216 final CharSequence address = input.subSequence(0, index);
217 if (isIPv6Std(address) || isIPv6HexCompressed(address)) {
218
219 final CharSequence scopeId = input.subSequence(index + 1, input.length());
220
221 return scopeId.length() != 0 && SCOPE_ID_PATTERN.matcher(scopeId).matches();
222 } else {
223 return false;
224 }
225 }
226 }
227
228
229
230
231 @Deprecated
232 public static boolean isIPv6URLBracketedAddress(final String input) {
233 return isIPv6URLBracketed(input);
234 }
235
236
237
238
239
240
241
242
243
244 public static boolean isIPv6URLBracketed(final CharSequence input) {
245 if (input.length() == 0) {
246 return false;
247 }
248 return input.charAt(0) == '['
249 && input.charAt(input.length() - 1) == ']'
250 && isIPv6(input.subSequence(1, input.length() - 1));
251 }
252
253
254
255
256
257
258 public static void formatAddress(
259 final StringBuilder buffer,
260 final SocketAddress socketAddress) {
261 Args.notNull(buffer, "buffer");
262 if (socketAddress instanceof InetSocketAddress) {
263 final InetSocketAddress socketaddr = (InetSocketAddress) socketAddress;
264 final InetAddress inetaddr = socketaddr.getAddress();
265 if (inetaddr != null) {
266 buffer.append(inetaddr.getHostAddress()).append(':').append(socketaddr.getPort());
267 } else {
268 buffer.append(socketAddress);
269 }
270 } else {
271 buffer.append(socketAddress);
272 }
273 }
274
275
276
277
278
279
280 public static String getCanonicalLocalHostName() {
281 try {
282 final InetAddress localHost = InetAddress.getLocalHost();
283 return localHost.getCanonicalHostName();
284 } catch (final UnknownHostException ex) {
285 return "localhost";
286 }
287 }
288
289 }