I'm writing a program that adds all network interfaces with multiple parameters to a list.
I have written the following code, which should work out of the box on any Linux system with Python and ethtool installed:
import imp
import os
import subprocess
import re
from enum import Enum
class interface_type(Enum):
OPTIC = 1
TWISTED_PAIR = 2
class NetworkInterface:
def set_indentifier(self, id):
self.id = id
def set_mac_address(self, mac):
self.mac = mac
def set_interface_type(self, interface_type):
self.interface_type = interface_type
def findNetworkInterfaces(ignoredInterface):
filteredList = netifaces.interfaces()
network_interfaces = []
for interface in filteredList:
for regex in ignoredInterface:
if re.search(regex, interface):
break
else:
nwi = NetworkInterface()
nwi.set_indentifier(interface)
nwi.set_mac_address(setMAC(interface))
nwi.set_interface_type(setInterfaceType(interface))
network_interfaces.append(nwi)
filteredList.remove(interface)
break
return network_interfaces
def setMAC(identifier):
addrs = netifaces.ifaddresses(identifier)
mac_address = addrs[netifaces.AF_LINK][0].get("addr")
return mac_address
def setInterfaceType(identifier):
bashCommand1 = "ethtool " + identifier
bashCommand2 = "grep ports"
try:
process1 = subprocess.Popen(bashCommand1.split(),
stdout=subprocess.PIPE)
process2 = subprocess.Popen(bashCommand2.split(),
stdin=process1.stdout, stdout=subprocess.PIPE)
output, error = process2.communicate()
except:
print ("Error determining interface type: " + error + "\n")
print ("Interface will be treated as Optical \n")
if "TP" in output:
return interface_type.TWISTED_PAIR
else:
return interface_type.OPTIC
if __name__ == "__main__":
ignored_interface = ["lo", "wlp2s0"]
try:
imp.find_module("netifaces")
netifaces_status = True
import netifaces
except ImportError as e:
print ("netifaces not found: " + str(e))
os.sys.exit(-1)
network_identifiers = findNetworkInterfaces(ignored_interface)
#print network_identifiers
for iface in network_identifiers:
print iface.id
print iface.mac
print iface.interface_type
I'm mainly concerned with the findNetworkInterfaces
function, as I feel I'm doing this in a very ineffecient way (basically copying the list and removing interfaces as to not have doubles). In this special case, I'm not concerned with PEP8 - this is something I'll do later. Any other suggestions to improve the code are very welcome.
1 Answer 1
Start writing in python3.x ;)
One regex to rule them all
Instead of looping over a the list to create a regex,
you could use the
|
char which will work as anor
so it can handle multiple outputsREGEX_FILTER = re.conmpile('lo|wlp2s0')
If you only need the parameters, a simple namedtuple will suffice
You could create a
namedtuple
that will get rid of the empty looking classIMHO setting the variables outside of the init is bad style
I would get the different variables needed before, and only then create the
NetworkInterface
object.
Note I will not review getting the interface type, since I am nowhere near a linux atm
Code
from collections import namedtuple
import re
import netifaces
FILTER_REGEX = re.compile(r'lo|wlp2s0')
NetworkInterface = namedtuple('NetworkInterface', ['iface', 'mac', 'type'])
def get_mac(iface):
addresses = netifaces.ifaddresses(iface)
return addresses[netifaces.AF_LINK][0].get("addr")
def get_type(iface):
"""Just return TP for testing"""
return "TP"
def find_network_interfaces():
for iface in netifaces.interfaces():
if FILTER_REGEX.search(iface):
continue
yield NetworkInterface(iface, get_mac(iface), get_type(iface))
if __name__ == '__main__':
for nwi in find_network_interfaces():
print(nwi.iface)
print(nwi.mac)
print(nwi.type)
-
1\$\begingroup\$ Since you saved the compiled regexes to a variable, you could do
FILTER_REGEX.search(iface)
. \$\endgroup\$Graipher– Graipher2019年01月21日 18:58:17 +00:00Commented Jan 21, 2019 at 18:58