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