1#!/usr/local/bin/python3
2
3print("ping fragments with IP option")
4
5# OO|--------|
6#          OO|----|
7
8import os
9from addr import *
10from scapy.all import *
11
12pid=os.getpid()
13eid=pid & 0xffff
14payload=b"ABCDEFGHIJKLMNOP"
15packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \
16    ICMP(type='echo-request', id=eid)/payload
17frag=[]
18fid=pid & 0xffff
19frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
20    flags='MF', options=IPOption_NOP())/bytes(packet)[20:36])
21frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
22    frag=2, options=IPOption_NOP())/bytes(packet)[36:44])
23eth=[]
24for f in frag:
25	eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f)
26
27if os.fork() == 0:
28	time.sleep(1)
29	sendp(eth, iface=LOCAL_IF)
30	os._exit(0)
31
32ans=sniff(iface=LOCAL_IF, timeout=3, filter=
33    "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp")
34for a in ans:
35	if a and a.type == ETH_P_IP and \
36	    a.payload.proto == 1 and \
37	    a.payload.frag == 0 and a.payload.flags == 0 and \
38	    icmptypes[a.payload.payload.type] == 'echo-reply':
39		id=a.payload.payload.id
40		print("id=%#x" % (id))
41		if id != eid:
42			print("WRONG ECHO REPLY ID")
43			exit(2)
44		data=a.payload.payload.payload.load
45		print("payload=%s" % (data))
46		if data == payload:
47			exit(0)
48		print("PAYLOAD!=%s" % (payload))
49		exit(1)
50print("NO ECHO REPLY")
51exit(2)
52