feat: implement packet sniffer with database integration and API endpoints
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 9s

This commit is contained in:
2025-11-25 13:40:13 +01:00
parent be54e665c4
commit 689e8aa717
5 changed files with 141 additions and 8 deletions

View File

@@ -0,0 +1,86 @@
import asyncio
from scapy.all import sniff, Ether, IP
import asyncpg
from typing import List
import threading
DB_DSN = "postgresql://mitm_user:mitm_password@localhost:5432/mitm_db"
sniffer_tasks = {}
sniffer_threads = {}
async def db_insert_packet(pkt_info: dict):
conn = await asyncpg.connect(DB_DSN)
try:
await conn.execute("""
INSERT INTO packets(
iface, direction,
src_mac, dst_mac, eth_type,
src_ip, dst_ip, protocol,
length, ebpf_verdict, ebpf_chain, raw
)
VALUES(
$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12
);
""",
pkt_info["iface"],
pkt_info["direction"],
pkt_info["src_mac"],
pkt_info["dst_mac"],
pkt_info["eth_type"],
pkt_info["src_ip"],
pkt_info["dst_ip"],
pkt_info["protocol"],
pkt_info["length"],
pkt_info["ebpf_verdict"],
pkt_info["ebpf_chain"],
pkt_info["raw"]
)
finally:
await conn.close()
def handle_packet(pkt, iface):
"""
Scapy callback → run in thread.
"""
pkt_info = {
"iface": iface,
"direction": "unknown", # You can set eth0=ingress, eth1=egress
"src_mac": pkt[Ether].src if Ether in pkt else None,
"dst_mac": pkt[Ether].dst if Ether in pkt else None,
"eth_type": pkt[Ether].type if Ether in pkt else None,
"src_ip": pkt[IP].src if IP in pkt else None,
"dst_ip": pkt[IP].dst if IP in pkt else None,
"protocol": pkt[IP].proto if IP in pkt else None,
"length": len(pkt),
"ebpf_verdict": None, # will integrate later
"ebpf_chain": None,
"raw": bytes(pkt)
}
# push to asyncio loop
loop = asyncio.get_event_loop()
loop.create_task(db_insert_packet(pkt_info))
def start_sniffer_thread(iface: str):
def sniff_blocking():
sniff(prn=lambda x: handle_packet(x, iface), iface=iface, store=False)
thread = threading.Thread(target=sniff_blocking, daemon=True)
thread.start()
return thread
async def start_sniffing(interfaces: List[str]):
for iface in interfaces:
if iface in sniffer_threads:
continue
sniffer_threads[iface] = start_sniffer_thread(iface)
async def stop_sniffing():
# Scapy cannot easily stop sniff(), so we simply kill threads
sniffer_threads.clear()
return True