From e30e934272f16e3fa60454c37692034064a33a5c Mon Sep 17 00:00:00 2001 From: Alejandro Sirgo Rica Date: Tue, 1 Oct 2024 10:14:48 +0200 Subject: src: replace DEVICE env variable with get_ethernet_interface() Use a python function to obtain the main net interface. Detect the first ethernet inferface in use. Stop using the DEVICE environment variable. --- src/live/ogOperations.py | 6 ++--- src/log.py | 3 ++- src/utils/cache.py | 4 +-- src/utils/menu.py | 4 +-- src/utils/net.py | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 8 deletions(-) diff --git a/src/live/ogOperations.py b/src/live/ogOperations.py index 2f59711..48bb1ee 100644 --- a/src/live/ogOperations.py +++ b/src/live/ogOperations.py @@ -24,7 +24,7 @@ from src.live.parttypes import get_parttype from src.utils.image import * from src.utils.postinstall import configure_os -from src.utils.net import ethtool +from src.utils.net import * from src.utils.menu import generate_menu from src.utils.fs import * from src.utils.probe import os_probe, get_cache_dev_path @@ -343,7 +343,7 @@ class OgLiveOperations: f.truncate(0) def _poweroff_oglive(self, operation='poweroff'): - interface = os.getenv('DEVICE') + interface = get_ethernet_interface() cmd_ethtool = shlex.split(f'ethtool -s {interface} wol g') cmd_browser = shlex.split('pkill -9 browser') if shutil.which('busybox'): @@ -772,7 +772,7 @@ class OgLiveOperations: cache = get_cache_dev_path() disks = get_disks() - interface = os.getenv('DEVICE') + interface = get_ethernet_interface() link = ethtool(interface) json_body = { 'serial_number': '', 'disk_setup': [], diff --git a/src/log.py b/src/log.py index 9478bb7..13c625a 100644 --- a/src/log.py +++ b/src/log.py @@ -9,6 +9,7 @@ import logging import logging.config import os +from src.utils.net import get_ethernet_interface class OgError(Exception): @@ -67,7 +68,7 @@ def _default_logging_live(): 'samba': { 'class': 'logging.FileHandler', 'formatter': 'formatter.syslogtime', - 'filename': f'/opt/opengnsys/log/{getifaddr(os.getenv("DEVICE"))}.log', + 'filename': f'/opt/opengnsys/log/{getifaddr(get_ethernet_interface())}.log', } } rtlog = { diff --git a/src/utils/cache.py b/src/utils/cache.py index 374f8e0..6358c6a 100644 --- a/src/utils/cache.py +++ b/src/utils/cache.py @@ -10,7 +10,7 @@ import logging import os from src.utils.fs import mount_mkdir, umount -from src.utils.net import getifaddr +from src.utils.net import * from src.utils.probe import get_cache_dev_path OG_IMAGE_PATH = '/opt/opengnsys/images/' @@ -45,7 +45,7 @@ def write_cache_txt(content): """ Dumps content to /opt/opengnsys/log/{ip}.cache.txt """ - client_ip = getifaddr(os.getenv('DEVICE')) + client_ip = getifaddr(get_ethernet_interface()) with open(OGCLIENT_LOG_CACHE.format(ip=client_ip), 'w') as f: logging.debug('Writing cache contents to %s.cache.txt', client_ip) f.write(content) diff --git a/src/utils/menu.py b/src/utils/menu.py index 48e2641..b615d6f 100644 --- a/src/utils/menu.py +++ b/src/utils/menu.py @@ -13,7 +13,7 @@ Utility module for ogBrowser menu generation import os import socket -from src.utils.net import getifaddr, getifhwaddr, ethtool +from src.utils.net import * MENU_TEMPLATE = """
@@ -39,7 +39,7 @@ def generate_menu(part_setup): Writes html menu to /opt/opengnsys/log/{ip}.info.html based on a partition setup """ - device = os.getenv('DEVICE') + device = get_ethernet_interface() if not device: return False diff --git a/src/utils/net.py b/src/utils/net.py index 01c6f04..e842c0f 100644 --- a/src/utils/net.py +++ b/src/utils/net.py @@ -10,6 +10,73 @@ import array import fcntl import socket import struct +import psutil +import logging + +def is_ethernet(interface): + SIOCGIFHWADDR = 0x8927 + ARPHRD_ETHER = 1 + + try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + info = fcntl.ioctl( + s.fileno(), + SIOCGIFHWADDR, + struct.pack('256s', interface.encode('utf-8')[:15])) + if struct.unpack('H', info[16:18])[0] == ARPHRD_ETHER: + return True + return False + except IOError: + return False + finally: + s.close() + +def is_wifi(interface): + SIOCGIWNAME = 0x8B01 # Wireless-specific ioctl + + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + buffer = struct.pack('256s', interface.encode('utf-8')) + info = fcntl.ioctl(sock.fileno(), SIOCGIWNAME, buffer) + return True + except IOError: + return False + finally: + sock.close() + +def is_link_active(interface): + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + try: + # Get interface flags + ifreq = struct.pack('16sh', interface.encode('utf-8'), 0) + flags = struct.unpack('16sh', fcntl.ioctl(sock.fileno(), 0x8913, ifreq))[1] + + # Check if IFF_UP and IFF_RUNNING flags are set + if flags & 0x1 and flags & 0x40: + return True + else: + return False + except IOError: + return False + finally: + sock.close() + +def get_ethernet_interface(): + eth_interfaces = [] + interfaces = psutil.net_if_addrs() + for interface in interfaces: + if is_ethernet(interface) and not is_wifi(interface) and is_link_active(interface): + eth_interfaces.append(interface) + + if len(eth_interfaces) > 1: + logging.info(f'Multiple active ethernet interfaces found: {", ".join(eth_interfaces)}. Using {eth_interfaces[0]}') + + if not eth_interfaces: + logging.info('No valid ethernet interface found') + return None + + return eth_interfaces[0] def ethtool(interface): try: -- cgit v1.2.3-18-g5258