summaryrefslogtreecommitdiffstats
path: root/Lib/uuid.py
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-11-27 23:30:21 (GMT)
committerGitHub <noreply@github.com>2017-11-27 23:30:21 (GMT)
commitc9409f7c4533f75b11a4c44e839d95a1403f8a0a (patch)
tree768036656c294a2fec12c9480066abba70729f1c /Lib/uuid.py
parent39f0bb5ad0715dbfc0a2d5dd6d0ddea9e4c65ae2 (diff)
downloadcpython-c9409f7c4533f75b11a4c44e839d95a1403f8a0a.zip
cpython-c9409f7c4533f75b11a4c44e839d95a1403f8a0a.tar.gz
cpython-c9409f7c4533f75b11a4c44e839d95a1403f8a0a.tar.bz2
Revert "bpo-32107 - Better merge of #4494 (#4576)" (#4593)
This reverts commit 9522a218f7dff95c490ff359cc60e8c2af35f5c8.
Diffstat (limited to 'Lib/uuid.py')
-rw-r--r--Lib/uuid.py70
1 files changed, 11 insertions, 59 deletions
diff --git a/Lib/uuid.py b/Lib/uuid.py
index 9e7c672..020c6e7 100644
--- a/Lib/uuid.py
+++ b/Lib/uuid.py
@@ -342,29 +342,11 @@ def _popen(command, *args):
env=env)
return proc
-# For MAC (a.k.a. IEEE 802, or EUI-48) addresses, the second least significant
-# bit of the first octet signifies whether the MAC address is universally (0)
-# or locally (1) administered. Network cards from hardware manufacturers will
-# always be universally administered to guarantee global uniqueness of the MAC
-# address, but any particular machine may have other interfaces which are
-# locally administered. An example of the latter is the bridge interface to
-# the Touch Bar on MacBook Pros.
-#
-# This bit works out to be the 42nd bit counting from 1 being the least
-# significant, or 1<<41. We'll skip over any locally administered MAC
-# addresses, as it makes no sense to use those in UUID calculation.
-#
-# See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local
-
-def _is_universal(mac):
- return not (mac & (1 << 41))
-
def _find_mac(command, args, hw_identifiers, get_index):
- first_local_mac = None
try:
proc = _popen(command, *args.split())
if not proc:
- return None
+ return
with proc:
for line in proc.stdout:
words = line.lower().rstrip().split()
@@ -373,9 +355,8 @@ def _find_mac(command, args, hw_identifiers, get_index):
try:
word = words[get_index(i)]
mac = int(word.replace(b':', b''), 16)
- if _is_universal(mac):
+ if mac:
return mac
- first_local_mac = first_local_mac or mac
except (ValueError, IndexError):
# Virtual interfaces, such as those provided by
# VPNs, do not have a colon-delimited MAC address
@@ -385,7 +366,6 @@ def _find_mac(command, args, hw_identifiers, get_index):
pass
except OSError:
pass
- return first_local_mac or None
def _ifconfig_getnode():
"""Get the hardware address on Unix by running ifconfig."""
@@ -395,7 +375,6 @@ def _ifconfig_getnode():
mac = _find_mac('ifconfig', args, keywords, lambda i: i+1)
if mac:
return mac
- return None
def _ip_getnode():
"""Get the hardware address on Unix by running ip."""
@@ -403,7 +382,6 @@ def _ip_getnode():
mac = _find_mac('ip', 'link list', [b'link/ether'], lambda i: i+1)
if mac:
return mac
- return None
def _arp_getnode():
"""Get the hardware address on Unix by running arp."""
@@ -426,10 +404,8 @@ def _arp_getnode():
# This works on Linux, FreeBSD and NetBSD
mac = _find_mac('arp', '-an', [os.fsencode('(%s)' % ip_addr)],
lambda i: i+2)
- # Return None instead of 0.
if mac:
return mac
- return None
def _lanscan_getnode():
"""Get the hardware address on Unix by running lanscan."""
@@ -439,36 +415,32 @@ def _lanscan_getnode():
def _netstat_getnode():
"""Get the hardware address on Unix by running netstat."""
# This might work on AIX, Tru64 UNIX.
- first_local_mac = None
try:
proc = _popen('netstat', '-ia')
if not proc:
- return None
+ return
with proc:
words = proc.stdout.readline().rstrip().split()
try:
i = words.index(b'Address')
except ValueError:
- return None
+ return
for line in proc.stdout:
try:
words = line.rstrip().split()
word = words[i]
if len(word) == 17 and word.count(b':') == 5:
mac = int(word.replace(b':', b''), 16)
- if _is_universal(mac):
+ if mac:
return mac
- first_local_mac = first_local_mac or mac
except (ValueError, IndexError):
pass
except OSError:
pass
- return first_local_mac or None
def _ipconfig_getnode():
"""Get the hardware address on Windows by running ipconfig.exe."""
import os, re
- first_local_mac = None
dirs = ['', r'c:\windows\system32', r'c:\winnt\system32']
try:
import ctypes
@@ -486,23 +458,18 @@ def _ipconfig_getnode():
for line in pipe:
value = line.split(':')[-1].strip().lower()
if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value):
- mac = int(value.replace('-', ''), 16)
- if _is_universal(mac):
- return mac
- first_local_mac = first_local_mac or mac
- return first_local_mac or None
+ return int(value.replace('-', ''), 16)
def _netbios_getnode():
"""Get the hardware address on Windows using NetBIOS calls.
See http://support.microsoft.com/kb/118623 for details."""
import win32wnet, netbios
- first_local_mac = None
ncb = netbios.NCB()
ncb.Command = netbios.NCBENUM
ncb.Buffer = adapters = netbios.LANA_ENUM()
adapters._pack()
if win32wnet.Netbios(ncb) != 0:
- return None
+ return
adapters._unpack()
for i in range(adapters.length):
ncb.Reset()
@@ -521,11 +488,7 @@ def _netbios_getnode():
bytes = status.adapter_address[:6]
if len(bytes) != 6:
continue
- mac = int.from_bytes(bytes, 'big')
- if _is_universal(mac):
- return mac
- first_local_mac = first_local_mac or mac
- return first_local_mac or None
+ return int.from_bytes(bytes, 'big')
_generate_time_safe = _UuidCreate = None
@@ -638,19 +601,9 @@ def _windll_getnode():
return UUID(bytes=bytes_(_buffer.raw)).node
def _random_getnode():
- """Get a random node ID."""
- # RFC 4122, $4.1.6 says "For systems with no IEEE address, a randomly or
- # pseudo-randomly generated value may be used; see Section 4.5. The
- # multicast bit must be set in such addresses, in order that they will
- # never conflict with addresses obtained from network cards."
- #
- # The "multicast bit" of a MAC address is defined to be "the least
- # significant bit of the first octet". This works out to be the 41st bit
- # counting from 1 being the least significant bit, or 1<<40.
- #
- # See https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
+ """Get a random node ID, with eighth bit set as suggested by RFC 4122."""
import random
- return random.getrandbits(48) | (1 << 40)
+ return random.getrandbits(48) | 0x010000000000
_node = None
@@ -673,14 +626,13 @@ def getnode():
getters = [_unix_getnode, _ifconfig_getnode, _ip_getnode,
_arp_getnode, _lanscan_getnode, _netstat_getnode]
- for getter in getters:
+ for getter in getters + [_random_getnode]:
try:
_node = getter()
except:
continue
if _node is not None:
return _node
- return _random_getnode()
_last_timestamp = None