I was told to make a LAN test. As I was playing with Python anyway and wanted one test for both Linux and Windows, I decided to give it a try.
The test is working as follows. Two LAN interfaces will be connected to each other with one LAN cable. The script gets two MACs as command line parameter. An Ethernet packet will be created and sent in unicast from one interface to another and vice versa.
The first objective was to determine a network interface corresponding to the given MAC address. This could be solved OS independent with netifaces package. Some hacks were needed to get this packaged installed, namely it had to be compiled. I solved this by using MinGW. Visual Studio 2008 can be used too. So finding interfaces looks like this:
def get_eth_interface(mac): for iface in netifaces.interfaces(): a = netifaces.ifaddresses(iface) iface_addr = a[netifaces.AF_LINK]['addr'] if(mac.lower() == iface_addr): return iface return "none"
The second and most painful objective was RAW_SOCK and Ethernet packets. In Linux it is not a problem: one can use built-in socket objects:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW) s.bind((src_iface,ethernet.ETH_TYPE_ARP))
But Windows itself has only very limited raw socket support. After long searching I found some posts suggesting using pypcap (an interface to WinPcap). The installation was a little bit tricky because there was no installer for Python 2.7 and later, so I had to check out the latest version from project’s SVN repo and compile it myself. After that is was rather easy to implement packet sending/receiving.
There is one useful package that simplifies Ethernet packet creation: dpkt. Creating some simple Ethernet packet looks like this:
def build_packet(src_mac, dest_mac): packet = ethernet.Ethernet() packet.src = eth_aton(src_mac) packet.dst = eth_aton(dest_mac) packet.data = (TEST_DATA) packet.type = ethernet.ETH_TYPE_ARP return packet
And the last but not least was creating an executable for Windows. It was necessary because of the installation problems described above. I found a very actively developed project PyInstaller. With this you can create one executable file containing all needed libraries. Unfortunately it still cannot handle egg folders properly, so I had to tweak netifaces package to be included into the final executable.
And one more hack concerning creating Windows executable: always use sys.exit() and not simply exit(), because the executable will complain not finding such a function.
Finally I ended up with rather simple and OS independent script for LAN testing and some silver hair ;-)