1#!/usr/local/bin/python3
2
3print("ping fragment that overlaps fragment at index boundary and replace it")
4
5#                               index boundary 4096 |
6# |--------------|
7#                 ....
8#                     |--------------|
9#                                              |XXXX-----|
10#                                    |--------------|
11#                                                   |--------------|
12
13# this should trigger "frag tail overlap %d" and "frag head overlap %d"
14
15import os
16from addr import *
17from scapy.all import *
18
19pid=os.getpid()
20eid=pid & 0xffff
21payload=b"ABCDEFGHIJKLMNOP"
22dummy=b"01234567"
23fragsize=1024
24boundary=4096
25fragnum=int(boundary/fragsize)
26packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \
27    ICMP(type='echo-request', id=eid)/ \
28    (int((boundary+fragsize)/len(payload)) * payload)
29frag=[]
30fid=pid & 0xffff
31for i in range(fragnum-1):
32	frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
33	    frag=(i*fragsize)>>3, flags='MF')/
34	    bytes(packet)[20+i*fragsize:20+(i+1)*fragsize])
35frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
36    frag=(boundary-8)>>3, flags='MF')/
37    (dummy+bytes(packet)[20+boundary:20+boundary+8]))
38frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
39    frag=(boundary-fragsize)>>3, flags='MF')/
40    bytes(packet)[20+boundary-fragsize:20+boundary])
41frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
42    frag=(boundary)>>3)/bytes(packet)[20+boundary:])
43eth=[]
44for f in frag:
45	eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f)
46
47if os.fork() == 0:
48	time.sleep(1)
49	for e in eth:
50		sendp(e, iface=LOCAL_IF)
51		time.sleep(0.001)
52	os._exit(0)
53
54ans=sniff(iface=LOCAL_IF, timeout=3, filter=
55    "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp")
56for a in ans:
57	if a and a.type == ETH_P_IP and \
58	    a.payload.proto == 1 and \
59	    a.payload.frag == 0 and \
60	    icmptypes[a.payload.payload.type] == 'echo-reply':
61		id=a.payload.payload.id
62		print("id=%#x" % (id))
63		if id != eid:
64			print("WRONG ECHO REPLY ID")
65			exit(2)
66		exit(0)
67print("NO ECHO REPLY")
68exit(1)
69