xref: /freebsd/tests/sys/netpfil/pf/frag-adjhole.py (revision db100bd93036855c7688dc088b811dc7b660f51d)
1#!/usr/bin/env python3
2#
3# Copyright (c) 2025 Alexander Bluhm <bluhm@openbsd.org>
4
5from fragcommon import *
6
7# |--------|
8#          |--------|
9#      |-------|
10#                   |----|
11
12def send(src, dst, send_if, recv_if):
13	pid = os.getpid()
14	eid = pid & 0xffff
15	payload = b"ABCDEFGHIJKLMNOP" * 2
16	packet = sp.IP(src=src, dst=dst)/ \
17	    sp.ICMP(type='echo-request', id=eid) / payload
18	frag = []
19	fid = pid & 0xffff
20	frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
21	    flags='MF') / bytes(packet)[20:36])
22	frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
23	    frag=2, flags='MF') / bytes(packet)[36:52])
24	frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
25	    frag=1, flags='MF') / bytes(packet)[28:44])
26	frag.append(sp.IP(src=src, dst=dst, proto=1, id=fid,
27	    frag=4) / bytes(packet)[52:60])
28	eth=[]
29	for f in frag:
30		eth.append(sp.Ether()/f)
31	if os.fork() == 0:
32		time.sleep(1)
33		sp.sendp(eth, iface=send_if)
34		os._exit(0)
35
36	ans = sp.sniff(iface=recv_if, timeout=3, filter=
37	    "ip and src " + dst + " and dst " + src + " and icmp")
38	for a in ans:
39		if a and a.type == sp.ETH_P_IP and \
40		    a.payload.proto == 1 and \
41		    a.payload.frag == 0 and a.payload.flags == 0 and \
42		    sp.icmptypes[a.payload.payload.type] == 'echo-reply':
43			id = a.payload.payload.id
44			print("id=%#x" % (id))
45			if id != eid:
46				print("WRONG ECHO REPLY ID")
47				exit(2)
48			data = a.payload.payload.payload.load
49			print("payload=%s" % (data))
50			if data == payload:
51				exit(0)
52			print("PAYLOAD!=%s" % (payload))
53			exit(1)
54	print("NO ECHO REPLY")
55	exit(2)
56
57if __name__ == '__main__':
58	main(send)
59