4
\$\begingroup\$

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.

Ludisposed
11.8k2 gold badges41 silver badges91 bronze badges
asked Jan 21, 2019 at 15:31
\$\endgroup\$
0

1 Answer 1

5
\$\begingroup\$
  • Start writing in ;)

    End of Life for will happen pretty soon 1

  • 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 an or so it can handle multiple outputs

    REGEX_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 class

  • IMHO 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)
answered Jan 21, 2019 at 16:20
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Since you saved the compiled regexes to a variable, you could do FILTER_REGEX.search(iface). \$\endgroup\$ Commented Jan 21, 2019 at 18:58

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.