Path: blob/main/tests/sys/netpfil/pf/frag-overhole.py
39507 views
#!/usr/bin/env python31#2# Copyright (c) 2025 Alexander Bluhm <[email protected]>34from fragcommon import *56# index boundary 4096 |7# |--------------|8# ....9# |--------------|10# |----------|11# |XXXX----------|12# |XXXX----|13# |---|1415# this should trigger "frag tail overlap %d" and "frag head overlap %d"16def send(src, dst, send_if, recv_if):17pid = os.getpid()18eid = pid & 0xffff19payload = b"ABCDEFGHIJKLMNOP"20dummy = b"01234567"21fragsize = 102422boundary = 409623fragnum = int(boundary / fragsize)24packet = sp.IP(src=src, dst=dst)/ \25sp.ICMP(type='echo-request', id=eid)/ \26((int((boundary + fragsize) / len(payload)) + 1) * payload)27packet_length = len(packet)28frag = []29fid = pid & 0xffff30for i in range(fragnum-1):31frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,32frag=(i * fragsize)>>3, flags='MF')/33bytes(packet)[20 + i * fragsize:20 + (i + 1) * fragsize])34frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,35frag=(boundary - fragsize) >> 3, flags='MF')/36bytes(packet)[20 + boundary - fragsize:20 + boundary - len(dummy)])37frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,38frag=(boundary - len(dummy)) >> 3, flags='MF')/39(dummy+bytes(packet)[20 + boundary:20 + boundary + fragsize]))40frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,41frag=(boundary - 8 - len(dummy)) >> 3, flags='MF')/42(dummy+bytes(packet)[20 + boundary - 8:20 + boundary]))43frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,44frag=(boundary + fragsize) >> 3)/bytes(packet)[20 + boundary + fragsize:])45eth=[]46for f in frag:47eth.append(sp.Ether() / f)4849if os.fork() == 0:50time.sleep(1)51for e in eth:52sp.sendp(e, iface=send_if)53time.sleep(0.001)54os._exit(0)5556ans = sp.sniff(iface=recv_if, timeout=3, filter=57"ip and src " + dst + " and dst " + src + " and icmp")58for a in ans:59if a and a.type == sp.ETH_P_IP and \60a.payload.proto == 1 and \61a.payload.frag == 0 and \62sp.icmptypes[a.payload.payload.type] == 'echo-reply':63id = a.payload.payload.id64print("id=%#x" % (id))65if id != eid:66print("WRONG ECHO REPLY ID")67exit(2)68if a and a.type == sp.ETH_P_IP and \69a.payload.proto == 1 and \70a.payload.frag > 0 and \71a.payload.flags == '':72length = (a.payload.frag << 3) + a.payload.len73print("len=%d" % (length))74if length != packet_length:75print("WRONG ECHO REPLY LENGTH")76exit(1)77exit(0)78print("NO ECHO REPLY")79exit(1)8081if __name__ == '__main__':82main(send)838485