Package: rawsocketpy
RawSocketPyAPI DocumentationRaw socket is a layer 2 python library for communication using the MAC addresses only.This allows you to create a custom made Ethernet/WiFi communication system which isnotusing IP nor TCP/UDP or to debug custom frames such as SERCOS III, Profibus, ARP, PTP, ...Python versions tested:2.7.x3.5.x3.8.xOSes:Linux 14.04Linux 16.04Linux 18.04Linux 20.04Not working on:Windows 10 - Due to Raw socket limitationMac OSX - Due to implementation (can likely be made working)Pros:Low levelNot using TCP-UDP/IPDead simpleCan broadcastMTU of 1500Asynchronous serverStateful capabilityCons:Low levelNot using TCP-UDP/IPNo encryptionNo fragmentationRequires rootMTU of 1500 (Ethernet frames)Installation# Soonsudo-Hpipinstallrawsocketpy# for now:gitclonehttps://github.com/AlexisTM/rawsocket_pythoncdrawsocket_python
sudopythonsetup.pyinstallFast testingOn one computer:sudopython-c"from rawsocketpy import RawSocketsock = RawSocket('wlp2s0', 0xEEFA)while True: print(sock.recv())"# 12:34:56:78:9A:BC == 0xEEFA => FF:FF:FF:FF:FF:FF - OK:# BooOnthe second computerover the same router (or same network on Zerotier):sudopython-c"from rawsocketpy import RawSocket; import timesock = RawSocket('wlp2s0', 0xEEFA)while True:sock.send('Boo')print('Boo has been sent')time.sleep(0.5)"In-depthfromrawsocketpyimportRawSocket# 0xEEFA is the ethertype# The most common are available here: https://en.wikipedia.org/wiki/EtherType# The full official list is available here: https://regauth.standards.ieee.org/standards-ra-web/pub/view.html#registries# Direct link: https://standards.ieee.org/develop/regauth/ethertype/eth.csv# You can use whatever you want but using a already use type can have unexpected behaviour.sock=RawSocket("wlp2s0",0xEEFA)sock.send("some data")# Broadcast "some data" with an ethertype of 0xEEFAsock.send("personal data",dest="\xAA\xBB\xCC\xDD\xEE\xFF")# Send "personal data to \xAA\xBB\xCC\xDD\xEE\xFF with an ether type of 0xEEFAsock.send("other data",ethertype="\xEE\xFF")# Broadcast "other data" with an ether type of 0xEEFFReceivingOn another machine, you can run the following:fromrawsocketpyimportRawSocket,to_strsock=RawSocket("wlp2s0",0xEEFA)packet=sock.recv()# The type of packet is RawPacket() which allows pretty printing and unmarshal the raw data.# If you are using Python2, all data is encoded as unicode strings "\x01.." while Python3 uses bytearray.print(packet)# Pretty printpacket.dest# string "\xFF\xFF\xFF\xFF\xFF\xFF" or bytearray(b"\xFF\xFF\xFF\xFF\xFF\xFF")packet.src# string "\x12\x12\x12\x12\x12\x13" or bytearray(b"\x12\x12\x12\x12\x12\x13")packet.type# string "\xEE\xFA" or bytearray([b"\xEE\xFA"]packegt.data# string "some data" or bytearray(b"some data"]print(to_str(packet.dest))# Human readable MAC:  FF:FF:FF:FF:FF:FFprint(to_str(packet.type,""))# Human readable type: EEFAStateless blocking ServerfromrawsocketpyimportRawServerclassLongTaskTest(RawRequestHandler):defhandle(self):time.sleep(1)print(self.packet)deffinish(self):print("End")defsetup(self):print("Begin")defmain():rs=RawServer("wlp2s0",0xEEFA,LongTaskTest)rs.spin()if__name__=='__main__':main()Stateful Asynchronous serverAvailableonlyifgeventis installed.fromrawsocketpyimportRawRequestHandler,RawAsyncServerCallbackimporttimedefcallback(handler,server):print("callback")handler.setup()handler.handle()handler.finish()classLongTaskTest(RawRequestHandler):defhandle(self):time.sleep(1)print(self.packet)deffinish(self):print("End")defsetup(self):print("Begin")defmain():rs=RawAsyncServerCallback("wlp2s0",0xEEFA,LongTaskTest,callback)rs.spin()if__name__=='__main__':main()I want to contribue!!You are free to contribue, the following capabilities are welcome:Windows compatibility (even possible?)MacOS compatibilityMore Python versions and OS testsBring a major refactor ;)CreditsAlexis PAQUES -@AlexisTM