This commit is contained in:
2025-04-06 03:14:47 +02:00
parent aaf9ab523b
commit b9c99befab
2263 changed files with 401112 additions and 20 deletions

View File

@ -0,0 +1,3 @@
from .getmac import __version__, get_mac_address
__all__ = ["get_mac_address"]

View File

@ -0,0 +1,123 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import argparse
import logging
import sys
from . import getmac
def main(): # type: () -> None
parser = argparse.ArgumentParser(
"getmac",
description="Get the MAC address of system network "
"interfaces or remote hosts on the LAN",
)
parser.add_argument(
"--version", action="version", version="getmac %s" % getmac.__version__
)
parser.add_argument(
"-v", "--verbose", action="store_true", help="Enable output messages"
)
parser.add_argument(
"-d",
"--debug",
action="count",
help="Enable debugging output. Add characters to "
"increase verbosity of output, e.g. '-dd'.",
)
parser.add_argument(
"-N",
"--no-net",
"--no-network-requests",
action="store_true",
dest="NO_NET",
help="Do not use arping or send a UDP packet to refresh the ARP table",
)
parser.add_argument(
"--override-port",
type=int,
metavar="PORT",
help="Override the default UDP port used to refresh the ARP table "
"if network requests are enabled and arping is unavailable",
)
parser.add_argument(
"--override-platform",
type=str,
default=None,
metavar="PLATFORM",
help="Override the platform detection with the given value "
"(e.g. 'linux', 'windows', 'freebsd', etc.'). "
"Any values returned by platform.system() are valid.",
)
parser.add_argument(
"--force-method",
type=str,
default=None,
metavar="METHOD",
help="Force a specific method to be used, e.g. 'IpNeighborShow'. "
"This will be used regardless of it's method type or platform "
"compatibility, and Method.test() will NOT be checked!",
)
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument(
"-i",
"--interface",
type=str,
default=None,
help="Name of a network interface on the system",
)
group.add_argument(
"-4", "--ip", type=str, default=None, help="IPv4 address of a remote host"
)
group.add_argument(
"-6", "--ip6", type=str, default=None, help="IPv6 address of a remote host"
)
group.add_argument(
"-n", "--hostname", type=str, default=None, help="Hostname of a remote host"
)
args = parser.parse_args()
if args.debug or args.verbose:
logging.basicConfig(
format="%(levelname)-8s %(message)s", level=logging.DEBUG, stream=sys.stderr
)
if args.debug:
getmac.DEBUG = args.debug
if args.override_port:
port = int(args.override_port)
getmac.log.debug(
"Using UDP port %d (overriding the default port %d)", port, getmac.PORT
)
getmac.PORT = port
if args.override_platform:
getmac.OVERRIDE_PLATFORM = args.override_platform.strip().lower()
if args.force_method:
getmac.FORCE_METHOD = args.force_method.strip().lower()
mac = getmac.get_mac_address(
interface=args.interface,
ip=args.ip,
ip6=args.ip6,
hostname=args.hostname,
network_request=not args.NO_NET,
)
if mac is not None:
print(mac) # noqa: T001, T201
sys.exit(0) # Exit success!
else:
sys.exit(1) # Exit with error since it failed to find a MAC
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
# This is a stopgap to maintain Python 2.7 support for the 0.9.0 release.
#
# Code copied from the "shutilwhich" project by Marc Brinkmann (@mbr)
# Source: https://github.com/mbr/shutilwhich
#
# We can't depend on it in setup.py since getmac has the __version__,
# which is imported in setup.py, which requires shutilwhich to be installed,
# leading to the typical problem: which came first, the Python or the Egg? :)
import os
import sys
# Everything below this point has been copied verbatim from the Python-3.3
# sources.
def which(cmd, mode=os.F_OK | os.X_OK, path=None):
"""Given a command, mode, and a PATH string, return the path which
conforms to the given mode on the PATH, or None if there is no such
file.
`mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
of os.environ.get("PATH"), or can be overridden with a custom search
path.
"""
# Check that a given file can be accessed with the correct mode.
# Additionally check that `file` is not a directory, as on Windows
# directories pass the os.access check.
def _access_check(fn, mode):
return os.path.exists(fn) and os.access(fn, mode) and not os.path.isdir(fn)
# Short circuit. If we're given a full path which matches the mode
# and it exists, we're done here.
if _access_check(cmd, mode):
return cmd
path = (path or os.environ.get("PATH", os.defpath)).split(os.pathsep)
if sys.platform == "win32":
# The current directory takes precedence on Windows.
if os.curdir not in path:
path.insert(0, os.curdir)
# PATHEXT is necessary to check on Windows.
pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
# See if the given file matches any of the expected path extensions.
# This will allow us to short circuit when given "python.exe".
matches = [cmd for ext in pathext if cmd.lower().endswith(ext.lower())]
# If it does match, only test that one, otherwise we have to try
# others.
files = [cmd] if matches else [cmd + ext.lower() for ext in pathext]
else:
# On other platforms you don't have things like PATHEXT to tell you
# what file suffixes are executable, so just pass on cmd as-is.
files = [cmd]
seen = set()
for dir in path:
dir = os.path.normcase(dir)
if dir not in seen:
seen.add(dir)
for thefile in files:
name = os.path.join(dir, thefile)
if _access_check(name, mode):
return name
return None