Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.
Based on patch by Aivars Kalvāns.
This commit is contained in:
parent
8e92f57274
commit
e66bb96929
|
@ -319,6 +319,24 @@ class TestUUID(unittest.TestCase):
|
||||||
if node is not None:
|
if node is not None:
|
||||||
self.check_node(node, 'ifconfig')
|
self.check_node(node, 'ifconfig')
|
||||||
|
|
||||||
|
@unittest.skipUnless(os.name == 'posix', 'requires Posix')
|
||||||
|
def test_arp_getnode(self):
|
||||||
|
node = uuid._arp_getnode()
|
||||||
|
if node is not None:
|
||||||
|
self.check_node(node, 'arp')
|
||||||
|
|
||||||
|
@unittest.skipUnless(os.name == 'posix', 'requires Posix')
|
||||||
|
def test_lanscan_getnode(self):
|
||||||
|
node = uuid._lanscan_getnode()
|
||||||
|
if node is not None:
|
||||||
|
self.check_node(node, 'lanscan')
|
||||||
|
|
||||||
|
@unittest.skipUnless(os.name == 'posix', 'requires Posix')
|
||||||
|
def test_netstat_getnode(self):
|
||||||
|
node = uuid._netstat_getnode()
|
||||||
|
if node is not None:
|
||||||
|
self.check_node(node, 'netstat')
|
||||||
|
|
||||||
@unittest.skipUnless(os.name == 'nt', 'requires Windows')
|
@unittest.skipUnless(os.name == 'nt', 'requires Windows')
|
||||||
def test_ipconfig_getnode(self):
|
def test_ipconfig_getnode(self):
|
||||||
node = uuid._ipconfig_getnode()
|
node = uuid._ipconfig_getnode()
|
||||||
|
|
69
Lib/uuid.py
69
Lib/uuid.py
|
@ -311,7 +311,7 @@ class UUID(object):
|
||||||
if self.variant == RFC_4122:
|
if self.variant == RFC_4122:
|
||||||
return int((self.int >> 76) & 0xf)
|
return int((self.int >> 76) & 0xf)
|
||||||
|
|
||||||
def _find_mac(command, args, hw_identifiers, get_index):
|
def _popen(command, args):
|
||||||
import os, shutil
|
import os, shutil
|
||||||
executable = shutil.which(command)
|
executable = shutil.which(command)
|
||||||
if executable is None:
|
if executable is None:
|
||||||
|
@ -319,20 +319,27 @@ def _find_mac(command, args, hw_identifiers, get_index):
|
||||||
executable = shutil.which(command, path=path)
|
executable = shutil.which(command, path=path)
|
||||||
if executable is None:
|
if executable is None:
|
||||||
return None
|
return None
|
||||||
|
# LC_ALL to ensure English output, 2>/dev/null to prevent output on
|
||||||
|
# stderr (Note: we don't have an example where the words we search for
|
||||||
|
# are actually localized, but in theory some system could do so.)
|
||||||
|
cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args)
|
||||||
|
return os.popen(cmd)
|
||||||
|
|
||||||
|
def _find_mac(command, args, hw_identifiers, get_index):
|
||||||
try:
|
try:
|
||||||
# LC_ALL to ensure English output, 2>/dev/null to prevent output on
|
pipe = _popen(command, args)
|
||||||
# stderr (Note: we don't have an example where the words we search for
|
if not pipe:
|
||||||
# are actually localized, but in theory some system could do so.)
|
return
|
||||||
cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args)
|
with pipe:
|
||||||
with os.popen(cmd) as pipe:
|
|
||||||
for line in pipe:
|
for line in pipe:
|
||||||
words = line.lower().split()
|
words = line.lower().rstrip().split()
|
||||||
for i in range(len(words)):
|
for i in range(len(words)):
|
||||||
if words[i] in hw_identifiers:
|
if words[i] in hw_identifiers:
|
||||||
try:
|
try:
|
||||||
return int(
|
word = words[get_index(i)]
|
||||||
words[get_index(i)].replace(':', ''), 16)
|
mac = int(word.replace(':', ''), 16)
|
||||||
|
if mac:
|
||||||
|
return mac
|
||||||
except (ValueError, IndexError):
|
except (ValueError, IndexError):
|
||||||
# Virtual interfaces, such as those provided by
|
# Virtual interfaces, such as those provided by
|
||||||
# VPNs, do not have a colon-delimited MAC address
|
# VPNs, do not have a colon-delimited MAC address
|
||||||
|
@ -345,27 +352,50 @@ def _find_mac(command, args, hw_identifiers, get_index):
|
||||||
|
|
||||||
def _ifconfig_getnode():
|
def _ifconfig_getnode():
|
||||||
"""Get the hardware address on Unix by running ifconfig."""
|
"""Get the hardware address on Unix by running ifconfig."""
|
||||||
|
|
||||||
# This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.
|
# This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.
|
||||||
for args in ('', '-a', '-av'):
|
for args in ('', '-a', '-av'):
|
||||||
mac = _find_mac('ifconfig', args, ['hwaddr', 'ether'], lambda i: i+1)
|
mac = _find_mac('ifconfig', args, ['hwaddr', 'ether'], lambda i: i+1)
|
||||||
if mac:
|
if mac:
|
||||||
return mac
|
return mac
|
||||||
|
|
||||||
import socket
|
def _arp_getnode():
|
||||||
|
"""Get the hardware address on Unix by running arp."""
|
||||||
|
import os, socket
|
||||||
ip_addr = socket.gethostbyname(socket.gethostname())
|
ip_addr = socket.gethostbyname(socket.gethostname())
|
||||||
|
|
||||||
# Try getting the MAC addr from arp based on our IP address (Solaris).
|
# Try getting the MAC addr from arp based on our IP address (Solaris).
|
||||||
mac = _find_mac('arp', '-an', [ip_addr], lambda i: -1)
|
return _find_mac('arp', '-an', [ip_addr], lambda i: -1)
|
||||||
if mac:
|
|
||||||
return mac
|
|
||||||
|
|
||||||
|
def _lanscan_getnode():
|
||||||
|
"""Get the hardware address on Unix by running lanscan."""
|
||||||
# This might work on HP-UX.
|
# This might work on HP-UX.
|
||||||
mac = _find_mac('lanscan', '-ai', ['lan0'], lambda i: 0)
|
return _find_mac('lanscan', '-ai', ['lan0'], lambda i: 0)
|
||||||
if mac:
|
|
||||||
return mac
|
|
||||||
|
|
||||||
return None
|
def _netstat_getnode():
|
||||||
|
"""Get the hardware address on Unix by running netstat."""
|
||||||
|
# This might work on AIX, Tru64 UNIX and presumably on IRIX.
|
||||||
|
try:
|
||||||
|
pipe = _popen('netstat', '-ia')
|
||||||
|
if not pipe:
|
||||||
|
return
|
||||||
|
with pipe:
|
||||||
|
words = pipe.readline().rstrip().split()
|
||||||
|
try:
|
||||||
|
i = words.index('Address')
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
for line in pipe:
|
||||||
|
try:
|
||||||
|
words = line.rstrip().split()
|
||||||
|
word = words[i]
|
||||||
|
if len(word) == 17 and word.count(':') == 5:
|
||||||
|
mac = int(word.replace(':', ''), 16)
|
||||||
|
if mac:
|
||||||
|
return mac
|
||||||
|
except (ValueError, IndexError):
|
||||||
|
pass
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
def _ipconfig_getnode():
|
def _ipconfig_getnode():
|
||||||
"""Get the hardware address on Windows by running ipconfig.exe."""
|
"""Get the hardware address on Windows by running ipconfig.exe."""
|
||||||
|
@ -506,7 +536,8 @@ def getnode():
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
|
getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
|
||||||
else:
|
else:
|
||||||
getters = [_unixdll_getnode, _ifconfig_getnode]
|
getters = [_unixdll_getnode, _ifconfig_getnode, _arp_getnode,
|
||||||
|
_lanscan_getnode, _netstat_getnode]
|
||||||
|
|
||||||
for getter in getters + [_random_getnode]:
|
for getter in getters + [_random_getnode]:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -36,6 +36,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.
|
||||||
|
Based on patch by Aivars Kalvāns.
|
||||||
|
|
||||||
- Issue #22769: Fixed ttk.Treeview.tag_has() when called without arguments.
|
- Issue #22769: Fixed ttk.Treeview.tag_has() when called without arguments.
|
||||||
|
|
||||||
- Issue #22417: Verify certificates by default in httplib (PEP 476).
|
- Issue #22417: Verify certificates by default in httplib (PEP 476).
|
||||||
|
|
Loading…
Reference in New Issue