You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
4.3 KiB
137 lines
4.3 KiB
#!/usr/bin/env python3
|
|
"""
|
|
Simple network interface utilities
|
|
"""
|
|
|
|
import platform
|
|
import re
|
|
import subprocess
|
|
|
|
|
|
def get_network_interfaces():
|
|
"""Get network interfaces with their IP addresses"""
|
|
try:
|
|
result = subprocess.run(
|
|
["/sbin/ip", "addr", "show"], capture_output=True, text=True, check=True
|
|
)
|
|
return _parse_ip_output(result.stdout)
|
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
try:
|
|
result = subprocess.run(["ifconfig"], capture_output=True, text=True, check=True)
|
|
return _parse_ifconfig_output(result.stdout)
|
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
return {}
|
|
|
|
|
|
def _parse_ip_output(output):
|
|
"""Parse 'ip addr' command output"""
|
|
interfaces = {}
|
|
current_interface = None
|
|
|
|
for line in output.split("\n"):
|
|
interface_match = re.match(r"^\d+:\s+(\w+):", line)
|
|
if interface_match:
|
|
current_interface = interface_match.group(1)
|
|
interfaces[current_interface] = []
|
|
|
|
ip_match = re.search(r"inet\s+(\d+\.\d+\.\d+\.\d+)", line)
|
|
if ip_match and current_interface:
|
|
interfaces[current_interface].append(ip_match.group(1))
|
|
|
|
return interfaces
|
|
|
|
|
|
def _parse_ifconfig_output(output):
|
|
"""Parse 'ifconfig' command output"""
|
|
interfaces = {}
|
|
current_interface = None
|
|
|
|
for line in output.split("\n"):
|
|
interface_match = re.match(r"^(\w+):", line)
|
|
if interface_match:
|
|
current_interface = interface_match.group(1)
|
|
interfaces[current_interface] = []
|
|
|
|
ip_match = re.search(r"inet\s+(\d+\.\d+\.\d+\.\d+)", line)
|
|
if ip_match and current_interface:
|
|
interfaces[current_interface].append(ip_match.group(1))
|
|
|
|
return interfaces
|
|
|
|
|
|
def find_interface_by_ip(target_ip):
|
|
"""Find interface name for given IP address"""
|
|
interfaces = get_network_interfaces()
|
|
for interface, ip_list in interfaces.items():
|
|
if target_ip in ip_list:
|
|
return interface
|
|
return None
|
|
|
|
|
|
def resolve_interface(interface: str) -> tuple[str, str]:
|
|
"""
|
|
Resolve interface parameter to actual network interface name and environment type
|
|
|
|
Args:
|
|
interface: "sim", "real", or direct interface name or IP address
|
|
|
|
Returns:
|
|
tuple: (interface_name, env_type) where env_type is "sim" or "real"
|
|
"""
|
|
# Check if interface is an IP address
|
|
if re.match(r"^\d+\.\d+\.\d+\.\d+$", interface):
|
|
if interface == "127.0.0.1":
|
|
return interface, "sim"
|
|
else:
|
|
return interface, "real"
|
|
|
|
if interface == "sim":
|
|
lo_interface = find_interface_by_ip("127.0.0.1")
|
|
if lo_interface:
|
|
# macOS uses lo0 instead of lo
|
|
if platform.system() == "Darwin" and lo_interface == "lo":
|
|
return "lo0", "sim"
|
|
return lo_interface, "sim"
|
|
return ("lo0" if platform.system() == "Darwin" else "lo"), "sim"
|
|
|
|
elif interface == "real":
|
|
interfaces = get_network_interfaces()
|
|
for iface, ip_list in interfaces.items():
|
|
for ip in ip_list:
|
|
if ip.startswith("192.168.123."):
|
|
return iface, "real"
|
|
return interface, "real" # fallback
|
|
|
|
else:
|
|
# Direct interface name - check if it has 127.0.0.1 to determine env_type
|
|
interfaces = get_network_interfaces()
|
|
if interface in interfaces:
|
|
for ip in interfaces[interface]:
|
|
if ip == "127.0.0.1":
|
|
return interface, "sim"
|
|
|
|
# macOS lo interface handling
|
|
if platform.system() == "Darwin" and interface == "lo":
|
|
return "lo0", "sim"
|
|
|
|
# Default to real for unknown interfaces
|
|
return interface, "real"
|
|
|
|
|
|
if __name__ == "__main__":
|
|
interfaces = get_network_interfaces()
|
|
|
|
if not interfaces:
|
|
print("No network interfaces found")
|
|
exit(1)
|
|
|
|
# Show all interfaces
|
|
print("Network interfaces:")
|
|
for interface, ip_list in interfaces.items():
|
|
print(f" {interface}: {', '.join(ip_list)}")
|
|
|
|
# Test resolve_interface function
|
|
print("\nTesting resolve_interface:")
|
|
for test_interface in ["sim", "real", "lo", "127.0.0.1"]:
|
|
interface_name, env_type = resolve_interface(test_interface)
|
|
print(f" {test_interface} -> {interface_name} ({env_type})")
|