1#!/usr/local/bin/python3
2# end of new fragment overlaps old one
3
4#     |>>>>>----|
5# |--------|
6
7# If the tail of the current framgent overlaps the beginning of an
8# older fragment, cut the older fragment.
9#                         m_adj(after->fe_m, aftercut);
10# The older data becomes more suspect, and we essentially cause it
11# to be dropped in the end, meaning it will come again.
12
13import os
14import threading
15from addr import *
16from scapy.all import *
17
18class Sniff1(threading.Thread):
19	filter = None
20	captured = None
21	packet = None
22	def run(self):
23		self.captured = sniff(iface=SRC_IF, filter=self.filter,
24		    count=1, timeout=3)
25		if self.captured:
26			self.packet = self.captured[0]
27
28dstaddr=sys.argv[1]
29pid=os.getpid()
30eid=pid & 0xffff
31payload=b"ABCDEFGHIJKLOMNO"
32dummy=b"01234567"
33packet=IP(src=SRC_OUT, dst=dstaddr)/ICMP(type='echo-request', id=eid)/payload
34fid=pid & 0xffff
35frag0=bytes(packet)[20:36]
36frag1=dummy+bytes(packet)[36:44]
37pkt0=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=fid, frag=0, flags='MF')/frag0
38pkt1=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=fid, frag=1)/frag1
39eth=[]
40eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
41eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
42
43sniffer = Sniff1();
44sniffer.filter = "ip and src %s and dst %s and icmp" % (dstaddr, SRC_OUT)
45sniffer.start()
46time.sleep(1)
47sendp(eth, iface=SRC_IF)
48sniffer.join(timeout=5)
49a = sniffer.packet
50
51if a and a.type == ETH_P_IP and \
52    a.payload.proto == 1 and \
53    a.payload.frag == 0 and a.payload.flags == 0 and \
54    icmptypes[a.payload.payload.type] == 'echo-reply':
55	id=a.payload.payload.id
56	print("id=%#x" % (id))
57	if id != eid:
58		print("WRONG ECHO REPLY ID")
59		exit(2)
60	load=a.payload.payload.payload.load
61	print("payload=%s" % (load))
62	if load == payload:
63		exit(0)
64	print("PAYLOAD!=%s" % (payload))
65	exit(1)
66print("NO ECHO REPLY")
67exit(2)
68