import asyncio import ctypes import fcntl import logging import signal import socket import struct logger = logging.getLogger(__name__) ETH_P_IP = 0x0800 IFF_PROMISC = 0x100 SIOCGIFFLAGS = 0x8913 SIOCSIFFLAGS = 0x8914 SIOCGSTAMP = 0x8906 class ifreq(ctypes.Structure): _fields_ = [("ifr_ifrn", ctypes.c_char * 16), ("ifr_flags", ctypes.c_short)] class timeval(ctypes.Structure): _fields_ = [("tv_sec", ctypes.c_long), ("tv_usec", ctypes.c_long)] PCAP_MAGIC_MICRO = 0xA1B2C3D4 PCAP_MAJ = 2 PCAP_MIN = 4 PCAP_SNAPLEN = 2048 LINKTYPE_ETHERNET = 1 async def do_pcap(devname="wlp2s0", pcapname="capture.pcap"): loop = asyncio.get_event_loop() if not isinstance(loop, asyncio.selector_events.BaseSelectorEventLoop): raise Exception("you gotta run it on linux") # because we're about to do some evil fuckery logger.info("opening packet capture") sock = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_IP)) sock.setblocking(False) # sock.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, devname) # NO htons on this call sock.bind((devname, ETH_P_IP)) logger.info("setting promisc mode") ifr = ifreq() ifr.ifr_ifrn = devname.encode() fcntl.ioctl(sock.fileno(), SIOCGIFFLAGS, ifr) ifr.ifr_flags |= IFF_PROMISC fcntl.ioctl(sock.fileno(), SIOCSIFFLAGS, ifr) logger.info("opening output file") outfile = open(pcapname, "wb") outfile.write(struct.pack("