xref: /openbsd-src/regress/sys/netinet/frag/frag_maxlen.py (revision 647ac4014c7881606258ecf2ee637195df4c98ac)
1*647ac401Sbluhm#!/usr/local/bin/python3
2cd130457Sbluhm
3*647ac401Sbluhmprint("fully fragmented maximum size ping packet, sent in random order")
4cd130457Sbluhm
5cd130457Sbluhm#          |----|
6cd130457Sbluhm#                                        |----|
7cd130457Sbluhm#                              |----|
8cd130457Sbluhm#                                                       |----|
9cd130457Sbluhm#     |----|
10cd130457Sbluhm
11cd130457Sbluhmimport os
12cd130457Sbluhmimport random
13cd130457Sbluhmfrom addr import *
14cd130457Sbluhmfrom scapy.all import *
15cd130457Sbluhm
16cd130457Sbluhmpid=os.getpid()
17cd130457Sbluhmeid=pid & 0xffff
18cd130457Sbluhmiplen=2**16
19cd130457Sbluhmsize=424
20*647ac401Sbluhmpayload=b"ABCDEFGHIJKLMNOP" * int(iplen / 16)
21cd130457Sbluhmpacket=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \
22*647ac401Sbluhm    ICMP(type='echo-request', id=eid)/bytes(payload)[0:iplen-20-8-1]
23cd130457Sbluhmfrag=[]
24cd130457Sbluhmfid=pid & 0xffff
25*647ac401Sbluhmmax=int((iplen-20)/size)
26cd130457Sbluhmfor i in range(max):
27cd130457Sbluhm	frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
28*647ac401Sbluhm	    frag=i*int(size/8), flags='MF')/
29*647ac401Sbluhm	    bytes(packet)[20+i*size:20+(i+1)*size])
30cd130457Sbluhmfrag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
31*647ac401Sbluhm    frag=max*int(size/8))/bytes(packet)[20+max*size:])
32cd130457Sbluhmeth=[]
33cd130457Sbluhmfor f in frag:
34cd130457Sbluhm	eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f)
35cd130457Sbluhm
36cd130457Sbluhmchild = os.fork()
37cd130457Sbluhmif child == 0:
38cd130457Sbluhm	time.sleep(1)
39cd130457Sbluhm	randeth=eth
40cd130457Sbluhm	random.shuffle(randeth)
41cd130457Sbluhm	for e in randeth:
42cd130457Sbluhm		sendp(e, iface=LOCAL_IF)
43cd130457Sbluhm		time.sleep(0.001)
44cd130457Sbluhm	os._exit(0)
45cd130457Sbluhm
46cd130457Sbluhmans=sniff(iface=LOCAL_IF, timeout=10, filter=
47cd130457Sbluhm    "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp")
48cd130457Sbluhmos.kill(child, 15)
49cd130457Sbluhmos.wait()
50cd130457Sbluhm
51cd130457Sbluhmfor a in ans:
52cd130457Sbluhm	if a and a.type == ETH_P_IP and \
53cd130457Sbluhm	    a.payload.frag == 0 and \
54cd130457Sbluhm	    a.payload.proto == 1 and \
55cd130457Sbluhm	    icmptypes[a.payload.payload.type] == 'echo-reply':
56cd130457Sbluhm		id=a.payload.payload.id
57*647ac401Sbluhm		print("id=%#x" % (id))
58cd130457Sbluhm		if id != eid:
59*647ac401Sbluhm			print("WRONG ECHO REPLY ID")
60cd130457Sbluhm			exit(2)
61cd130457Sbluhm		exit(0)
62*647ac401Sbluhmprint("NO ECHO REPLY")
63cd130457Sbluhmexit(1)
64