@@ -342,29 +342,11 @@ def _popen(command, *args):
342
342
env = env )
343
343
return proc
344
344
345
- # For MAC (a.k.a. IEEE 802, or EUI-48) addresses, the second least significant
346
- # bit of the first octet signifies whether the MAC address is universally (0)
347
- # or locally (1) administered. Network cards from hardware manufacturers will
348
- # always be universally administered to guarantee global uniqueness of the MAC
349
- # address, but any particular machine may have other interfaces which are
350
- # locally administered. An example of the latter is the bridge interface to
351
- # the Touch Bar on MacBook Pros.
352
- #
353
- # This bit works out to be the 42nd bit counting from 1 being the least
354
- # significant, or 1<<41. We'll skip over any locally administered MAC
355
- # addresses, as it makes no sense to use those in UUID calculation.
356
- #
357
- # See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local
358
-
359
- def _is_universal (mac ):
360
- return not (mac & (1 << 41 ))
361
-
362
345
def _find_mac (command , args , hw_identifiers , get_index ):
363
- first_local_mac = None
364
346
try :
365
347
proc = _popen (command , * args .split ())
366
348
if not proc :
367
- return None
349
+ return
368
350
with proc :
369
351
for line in proc .stdout :
370
352
words = line .lower ().rstrip ().split ()
@@ -373,9 +355,8 @@ def _find_mac(command, args, hw_identifiers, get_index):
373
355
try :
374
356
word = words [get_index (i )]
375
357
mac = int (word .replace (b':' , b'' ), 16 )
376
- if _is_universal ( mac ) :
358
+ if mac :
377
359
return mac
378
- first_local_mac = first_local_mac or mac
379
360
except (ValueError , IndexError ):
380
361
# Virtual interfaces, such as those provided by
381
362
# VPNs, do not have a colon-delimited MAC address
@@ -385,7 +366,6 @@ def _find_mac(command, args, hw_identifiers, get_index):
385
366
pass
386
367
except OSError :
387
368
pass
388
- return first_local_mac or None
389
369
390
370
def _ifconfig_getnode ():
391
371
"""Get the hardware address on Unix by running ifconfig."""
@@ -395,15 +375,13 @@ def _ifconfig_getnode():
395
375
mac = _find_mac ('ifconfig' , args , keywords , lambda i : i + 1 )
396
376
if mac :
397
377
return mac
398
- return None
399
378
400
379
def _ip_getnode ():
401
380
"""Get the hardware address on Unix by running ip."""
402
381
# This works on Linux with iproute2.
403
382
mac = _find_mac ('ip' , 'link list' , [b'link/ether' ], lambda i : i + 1 )
404
383
if mac :
405
384
return mac
406
- return None
407
385
408
386
def _arp_getnode ():
409
387
"""Get the hardware address on Unix by running arp."""
@@ -426,10 +404,8 @@ def _arp_getnode():
426
404
# This works on Linux, FreeBSD and NetBSD
427
405
mac = _find_mac ('arp' , '-an' , [os .fsencode ('(%s)' % ip_addr )],
428
406
lambda i : i + 2 )
429
- # Return None instead of 0.
430
407
if mac :
431
408
return mac
432
- return None
433
409
434
410
def _lanscan_getnode ():
435
411
"""Get the hardware address on Unix by running lanscan."""
@@ -439,36 +415,32 @@ def _lanscan_getnode():
439
415
def _netstat_getnode ():
440
416
"""Get the hardware address on Unix by running netstat."""
441
417
# This might work on AIX, Tru64 UNIX.
442
- first_local_mac = None
443
418
try :
444
419
proc = _popen ('netstat' , '-ia' )
445
420
if not proc :
446
- return None
421
+ return
447
422
with proc :
448
423
words = proc .stdout .readline ().rstrip ().split ()
449
424
try :
450
425
i = words .index (b'Address' )
451
426
except ValueError :
452
- return None
427
+ return
453
428
for line in proc .stdout :
454
429
try :
455
430
words = line .rstrip ().split ()
456
431
word = words [i ]
457
432
if len (word ) == 17 and word .count (b':' ) == 5 :
458
433
mac = int (word .replace (b':' , b'' ), 16 )
459
- if _is_universal ( mac ) :
434
+ if mac :
460
435
return mac
461
- first_local_mac = first_local_mac or mac
462
436
except (ValueError , IndexError ):
463
437
pass
464
438
except OSError :
465
439
pass
466
- return first_local_mac or None
467
440
468
441
def _ipconfig_getnode ():
469
442
"""Get the hardware address on Windows by running ipconfig.exe."""
470
443
import os , re
471
- first_local_mac = None
472
444
dirs = ['' , r'c:\windows\system32' , r'c:\winnt\system32' ]
473
445
try :
474
446
import ctypes
@@ -486,23 +458,18 @@ def _ipconfig_getnode():
486
458
for line in pipe :
487
459
value = line .split (':' )[- 1 ].strip ().lower ()
488
460
if re .match ('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]' , value ):
489
- mac = int (value .replace ('-' , '' ), 16 )
490
- if _is_universal (mac ):
491
- return mac
492
- first_local_mac = first_local_mac or mac
493
- return first_local_mac or None
461
+ return int (value .replace ('-' , '' ), 16 )
494
462
495
463
def _netbios_getnode ():
496
464
"""Get the hardware address on Windows using NetBIOS calls.
497
465
See http://support.microsoft.com/kb/118623 for details."""
498
466
import win32wnet , netbios
499
- first_local_mac = None
500
467
ncb = netbios .NCB ()
501
468
ncb .Command = netbios .NCBENUM
502
469
ncb .Buffer = adapters = netbios .LANA_ENUM ()
503
470
adapters ._pack ()
504
471
if win32wnet .Netbios (ncb ) != 0 :
505
- return None
472
+ return
506
473
adapters ._unpack ()
507
474
for i in range (adapters .length ):
508
475
ncb .Reset ()
@@ -521,11 +488,7 @@ def _netbios_getnode():
521
488
bytes = status .adapter_address [:6 ]
522
489
if len (bytes ) != 6 :
523
490
continue
524
- mac = int .from_bytes (bytes , 'big' )
525
- if _is_universal (mac ):
526
- return mac
527
- first_local_mac = first_local_mac or mac
528
- return first_local_mac or None
491
+ return int .from_bytes (bytes , 'big' )
529
492
530
493
531
494
_generate_time_safe = _UuidCreate = None
@@ -638,19 +601,9 @@ def _windll_getnode():
638
601
return UUID (bytes = bytes_ (_buffer .raw )).node
639
602
640
603
def _random_getnode ():
641
- """Get a random node ID."""
642
- # RFC 4122, $4.1.6 says "For systems with no IEEE address, a randomly or
643
- # pseudo-randomly generated value may be used; see Section 4.5. The
644
- # multicast bit must be set in such addresses, in order that they will
645
- # never conflict with addresses obtained from network cards."
646
- #
647
- # The "multicast bit" of a MAC address is defined to be "the least
648
- # significant bit of the first octet". This works out to be the 41st bit
649
- # counting from 1 being the least significant bit, or 1<<40.
650
- #
651
- # See https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
604
+ """Get a random node ID, with eighth bit set as suggested by RFC 4122."""
652
605
import random
653
- return random .getrandbits (48 ) | ( 1 << 40 )
606
+ return random .getrandbits (48 ) | 0x010000000000
654
607
655
608
656
609
_node = None
@@ -673,14 +626,13 @@ def getnode():
673
626
getters = [_unix_getnode , _ifconfig_getnode , _ip_getnode ,
674
627
_arp_getnode , _lanscan_getnode , _netstat_getnode ]
675
628
676
- for getter in getters :
629
+ for getter in getters + [ _random_getnode ] :
677
630
try :
678
631
_node = getter ()
679
632
except :
680
633
continue
681
634
if _node is not None :
682
635
return _node
683
- return _random_getnode ()
684
636
685
637
686
638
_last_timestamp = None
0 commit comments