16
16
package com .fasterxml .uuid ;
17
17
18
18
import java .io .Serializable ;
19
+ import java .net .DatagramSocket ;
20
+ import java .net .InetAddress ;
21
+ import java .net .InetSocketAddress ;
19
22
import java .net .NetworkInterface ;
23
+ import java .net .SocketException ;
20
24
import java .security .SecureRandom ;
21
25
import java .util .Enumeration ;
22
26
import java .util .Random ;
@@ -271,9 +275,9 @@ public static EthernetAddress fromInterface()
271
275
while (en .hasMoreElements ()) {
272
276
NetworkInterface nint = en .nextElement ();
273
277
if (!nint .isLoopback ()) {
274
- byte [] data = nint . getHardwareAddress ( );
275
- if (data != null && data . length == 6 ) {
276
- return new EthernetAddress ( data ) ;
278
+ EthernetAddress addr = fromInterface ( nint );
279
+ if (addr != null ) {
280
+ return addr ;
277
281
}
278
282
}
279
283
}
@@ -282,7 +286,75 @@ public static EthernetAddress fromInterface()
282
286
}
283
287
return null ;
284
288
}
285
-
289
+
290
+ /**
291
+ * A factory method to return the ethernet address of a specified network interface.
292
+ */
293
+ public static EthernetAddress fromInterface (NetworkInterface nint )
294
+ {
295
+ if (nint != null ) {
296
+ try {
297
+ byte [] data = nint .getHardwareAddress ();
298
+ if (data != null && data .length == 6 ) {
299
+ return new EthernetAddress (data );
300
+ }
301
+ } catch (SocketException e ) {
302
+ // could not get address
303
+ }
304
+ }
305
+ return null ;
306
+ }
307
+
308
+ /**
309
+ * A factory method that will try to determine the ethernet address of
310
+ * the network interface that connects to the default network gateway.
311
+ * To do this it will try to open a connection to one of the root DNS
312
+ * servers, or barring that, to address 1.1.1.1, or finally if that also
313
+ * fails then to IPv6 address "1::1". If a connection can be opened then
314
+ * the interface through which that connection is routed is determined
315
+ * to be the default egress interface, and the corresponding address of
316
+ * that interface will be returned. If all attempts are unsuccessful,
317
+ * null will be returned.
318
+ */
319
+ public static EthernetAddress fromEgressInterface ()
320
+ {
321
+ String roots = "abcdefghijklm" ;
322
+ int index = new Random ().nextInt (roots .length ());
323
+ String name = roots .charAt (index ) + ".root-servers.net" ;
324
+ InetSocketAddress externalAddress = new InetSocketAddress (name , 0 );
325
+ if (externalAddress .isUnresolved ()) {
326
+ externalAddress = new InetSocketAddress ("1.1.1.1" , 0 );
327
+ }
328
+ EthernetAddress ifAddr = fromEgressInterface (externalAddress );
329
+ if (ifAddr == null ) {
330
+ return fromEgressInterface (new InetSocketAddress ("1::1" , 0 ));
331
+ } else {
332
+ return ifAddr ;
333
+ }
334
+ }
335
+
336
+ /**
337
+ * A factory method to return the address of the interface used to route
338
+ * traffic to the specified IP address.
339
+ */
340
+ public static EthernetAddress fromEgressInterface (InetSocketAddress externalSocketAddress )
341
+ {
342
+ DatagramSocket socket = null ;
343
+ try {
344
+ socket = new DatagramSocket ();
345
+ socket .connect (externalSocketAddress );
346
+ InetAddress localAddress = socket .getLocalAddress ();
347
+ NetworkInterface egressIf = NetworkInterface .getByInetAddress (localAddress );
348
+ return fromInterface (egressIf );
349
+ } catch (SocketException e ) {
350
+ return null ;
351
+ } finally {
352
+ if (socket != null ) {
353
+ socket .close ();
354
+ }
355
+ }
356
+ }
357
+
286
358
/**
287
359
* Factory method that can be used to construct a random multicast
288
360
* address; to be used in cases where there is no "real" ethernet
0 commit comments