# Copyright (c) 2019 and onward National Institute for Subatomic Physics Nikhef
# SPDX-License-Identifier: MIT
import subprocess
import os
[docs]
def dump_hex(title, buf, cols=32):
"""
Dumps a buffer as hex
"""
print("%s:" % title)
for off in range(0, len(buf), cols):
as_hex = ["%02x" % v for v in buf[off:off + cols]]
print(" %04x: %s" % (off, " ".join(as_hex)))
print()
[docs]
class iface:
def __init__(name):
self.name = name
[docs]
def get_network_interfaces():
ip_locs = list(filter(lambda x : os.path.exists(x), ("/bin/ip", "/sbin/ip")))
if len(ip_locs) == 0:
raise RuntimeError("Can't locate IP utility")
ip_util = ip_locs[0]
links = subprocess.check_output([ip_util,"-o","link"]).decode('utf-8').split("\n")
addresses = subprocess.check_output([ip_util,"-o","address"]).decode('utf-8').split("\n")
interfaces = {}
# First create dict of linsk
for link in links:
if link.strip() == "":
continue
link = link.replace("\\", "")
tokens = link.split()
iface_name = tokens[1][:-1]
atwhere = iface_name.find("@")
if atwhere >= 0:
iface_name = iface_name[0:atwhere]
props = dict(zip(tokens[3::2], tokens[4::2]))
props['flags'] = tokens[2][1:-1].split(",")
props['addresses'] = []
interfaces[iface_name] = props
for address in addresses:
if address.strip() == "":
continue
address = address.replace("\\", "")
tokens = address.split()
iface_name = tokens[1]
props = dict(zip(tokens[2::2], tokens[3::2]))
interfaces[iface_name]['addresses'].append(props)
return interfaces
[docs]
def get_nic_info(iface_name, check_mtu=True):
# First get network information
ifaces = get_network_interfaces()
if not iface_name in ifaces:
raise RuntimeError(f"Interface {iface_name} does not exists")
iface = ifaces[iface_name]
if 'link/ether' not in iface:
raise RuntimeError(f"Could not retrieve MAC form {iface_name}")
mac = iface['link/ether']
if 'mtu' in iface:
if int(iface['mtu']) < 9000:
print(f"Warning: interface {iface_name} MTU not set to 9000 or higher, packets may be lost!")
for addr in iface['addresses']:
if 'inet' in addr:
ip = addr['inet']
break
else:
raise RuntimeError(f"Network inteface {iface_name} does not appear to have an IPv4 address")
# remove netmask part
ip,_ = ip.split("/")
return mac, ip
[docs]
def inc_ip(ip):
ipc = [int(x) for x in ip.split(".")]
ipc[3] += 1
if ipc[3] > 254: ipc[3] = 1
return ".".join(str(x) for x in ipc)
if __name__ == "__main__":
print(get_network_interfaces())