diff --git a/python/pcap/memecap.py b/python/pcap/memecap.py new file mode 100644 index 0000000..2475512 --- /dev/null +++ b/python/pcap/memecap.py @@ -0,0 +1,107 @@ +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"): + if isinstance(devname, str): + devname = devname.encode() + + 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) + + logger.info("setting promisc mode") + ifr = ifreq() + ifr.ifr_ifrn = devname + 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("