network/module_utils/network_lsr/ethtool.py
Rich Megginson f5ff30a66c fix most ansible-test issues, suppress the rest
Automation Hub, and possibly Galaxy in the future, require the
collection to be screened with `ansible-test sanity` among other
checks.  The role had a number of issues:
* Use `AssertionError` instead of `assert`
* Use of `logging` module not in accordance with standards, but these
  are ok and the errors were suppressed
* Several import errors which are ok because they are checked
  elsewhere
* __init__.py in the module_utils directories must be empty, so a
  new file myerror.py was added to move the code from __init__.py
  * NOTE: network_lsr/nm/__init__.py is not empty
* The documentation block in the module was not properly constructed
  or formatted.
* shellcheck issues, including removing unused files
* use `unused` instead of `_` (underscore) for variables that are
  unused

add WARNING to module docs - collection users should not use directly

Signed-off-by: Rich Megginson <rmeggins@redhat.com>
2021-04-09 19:57:55 +02:00

60 lines
1.7 KiB
Python

# SPDX-License-Identifier: BSD-3-Clause
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import array
import struct
import fcntl
import socket
from .utils import Util
ETHTOOL_GPERMADDR = 0x00000020
SIOCETHTOOL = 0x8946
MAX_ADDR_LEN = 32
IFNAMESIZ = 16
def get_perm_addr(ifname):
"""
Return the Permanent address value for the specified interface using the
ETHTOOL_GPERMADDR ioctl command.
Please for further documentation, see:
https://github.com/torvalds/linux/blob/master/include/uapi/linux/ethtool.h#L734
https://github.com/torvalds/linux/blob/master/include/uapi/linux/ethtool.h#L1388
https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/tree/ethtool.c#n4172
"""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockfd = sock.fileno()
ifname = ifname.encode("utf-8")
if len(ifname) > IFNAMESIZ:
return None
ecmd = array.array(
"B",
struct.pack(
"II%is" % MAX_ADDR_LEN,
ETHTOOL_GPERMADDR,
MAX_ADDR_LEN,
b"\x00" * MAX_ADDR_LEN,
),
)
ifreq = struct.pack("%isP" % IFNAMESIZ, ifname, ecmd.buffer_info()[0])
fcntl.ioctl(sockfd, SIOCETHTOOL, ifreq)
try:
res = ecmd.tobytes()
except AttributeError: # tobytes() is not available in python2
res = ecmd.tostring()
unused, size, perm_addr = struct.unpack("II%is" % MAX_ADDR_LEN, res)
perm_addr = Util.mac_ntoa(perm_addr[:size])
except IOError:
perm_addr = None
finally:
sock.close()
return perm_addr