summaryrefslogtreecommitdiffstats
path: root/Lib/uuid.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2014-11-07 10:23:30 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2014-11-07 10:23:30 (GMT)
commit57b967791a552656f4c21a4af283788269d06d83 (patch)
tree5beacad006e57361a7dd1131283d28aec3c07a8f /Lib/uuid.py
parent7c28999cb2d46da5b688ae1a9fb4e63666628541 (diff)
parente66bb9692977c66ffcbe9af64642ab5977879a9a (diff)
downloadcpython-57b967791a552656f4c21a4af283788269d06d83.zip
cpython-57b967791a552656f4c21a4af283788269d06d83.tar.gz
cpython-57b967791a552656f4c21a4af283788269d06d83.tar.bz2
Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.
Based on patch by Aivars Kalvāns.
Diffstat (limited to 'Lib/uuid.py')
-rw-r--r--Lib/uuid.py83
1 files changed, 55 insertions, 28 deletions
diff --git a/Lib/uuid.py b/Lib/uuid.py
index 018bb6f..598aea1 100644
--- a/Lib/uuid.py
+++ b/Lib/uuid.py
@@ -304,7 +304,7 @@ class UUID(object):
if self.variant == RFC_4122:
return int((self.int >> 76) & 0xf)
-def _find_mac(command, arg, hw_identifiers, get_index):
+def _popen(command, *args):
import os, shutil, subprocess
executable = shutil.which(command)
if executable is None:
@@ -312,28 +312,32 @@ def _find_mac(command, arg, hw_identifiers, get_index):
executable = shutil.which(command, path=path)
if executable is None:
return None
-
+ # LC_ALL=C to ensure English output, stderr=DEVNULL 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.)
+ env = dict(os.environ)
+ env['LC_ALL'] = 'C'
+ proc = subprocess.Popen((executable,) + args,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.DEVNULL,
+ env=env)
+ return proc
+
+def _find_mac(command, args, hw_identifiers, get_index):
try:
- # LC_ALL=C to ensure English output, stderr=DEVNULL 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.)
- env = dict(os.environ)
- env['LC_ALL'] = 'C'
- cmd = [executable]
- if arg:
- cmd.append(arg)
- proc = subprocess.Popen(cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.DEVNULL,
- env=env)
+ proc = _popen(command, *args.split())
+ if not proc:
+ return
with proc:
for line in proc.stdout:
- words = line.lower().split()
+ words = line.lower().rstrip().split()
for i in range(len(words)):
if words[i] in hw_identifiers:
try:
- return int(
- words[get_index(i)].replace(b':', b''), 16)
+ word = words[get_index(i)]
+ mac = int(word.replace(b':', b''), 16)
+ if mac:
+ return mac
except (ValueError, IndexError):
# Virtual interfaces, such as those provided by
# VPNs, do not have a colon-delimited MAC address
@@ -346,28 +350,50 @@ def _find_mac(command, arg, hw_identifiers, get_index):
def _ifconfig_getnode():
"""Get the hardware address on Unix by running ifconfig."""
- import os
-
# This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.
for args in ('', '-a', '-av'):
mac = _find_mac('ifconfig', args, [b'hwaddr', b'ether'], lambda i: i+1)
if 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())
# Try getting the MAC addr from arp based on our IP address (Solaris).
- mac = _find_mac('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1)
- if mac:
- return mac
+ return _find_mac('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1)
+def _lanscan_getnode():
+ """Get the hardware address on Unix by running lanscan."""
# This might work on HP-UX.
- mac = _find_mac('lanscan', '-ai', [b'lan0'], lambda i: 0)
- if mac:
- return mac
+ return _find_mac('lanscan', '-ai', [b'lan0'], lambda i: 0)
- 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:
+ proc = _popen('netstat', '-ia')
+ if not proc:
+ return
+ with proc:
+ words = proc.stdout.readline().rstrip().split()
+ try:
+ i = words.index(b'Address')
+ except ValueError:
+ 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 mac:
+ return mac
+ except (ValueError, IndexError):
+ pass
+ except OSError:
+ pass
def _ipconfig_getnode():
"""Get the hardware address on Windows by running ipconfig.exe."""
@@ -509,7 +535,8 @@ def getnode():
if sys.platform == 'win32':
getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
else:
- getters = [_unixdll_getnode, _ifconfig_getnode]
+ getters = [_unixdll_getnode, _ifconfig_getnode, _arp_getnode,
+ _lanscan_getnode, _netstat_getnode]
for getter in getters + [_random_getnode]:
try: