1#!/usr/local/bin/python2.7
2# send 3 non-overlapping ping6 fragments in all possible orders
3
4# |----|
5#      |----|
6#           |----|
7
8import os
9from addr import *
10from scapy.all import *
11
12permute=[]
13permute.append([0,1,2])
14permute.append([0,2,1])
15permute.append([1,0,2])
16permute.append([2,0,1])
17permute.append([1,2,0])
18permute.append([2,1,0])
19
20pid=os.getpid() & 0xffff
21payload="ABCDEFGHIJKLMNOP"
22for p in permute:
23	pid += 1
24	packet=IPv6(src=SRC_OUT6, dst=DST_IN6)/ \
25	    ICMPv6EchoRequest(id=pid, data=payload)
26	frag=[]
27	frag.append(IPv6ExtHdrFragment(nh=58, id=pid, m=1)/ \
28	    str(packet)[40:48])
29	frag.append(IPv6ExtHdrFragment(nh=58, id=pid, offset=1, m=1)/ \
30	    str(packet)[48:56])
31	frag.append(IPv6ExtHdrFragment(nh=58, id=pid, offset=2)/ \
32	    str(packet)[56:64])
33	eth=[]
34	for i in range(3):
35		pkt=IPv6(src=SRC_OUT6, dst=DST_IN6)/frag[p[i]]
36		eth.append(Ether(src=SRC_MAC, dst=DST_MAC)/pkt)
37
38	if os.fork() == 0:
39		time.sleep(1)
40		sendp(eth, iface=SRC_IF)
41		os._exit(0)
42
43	ans=sniff(iface=SRC_IF, timeout=3, filter=
44	    "ip6 and src "+DST_IN6+" and dst "+SRC_OUT6+" and icmp6")
45	for a in ans:
46		if a and a.type == ETH_P_IPV6 and \
47		    ipv6nh[a.payload.nh] == 'ICMPv6' and \
48		    icmp6types[a.payload.payload.type] == 'Echo Reply':
49			id=a.payload.payload.id
50			print "id=%#x" % (id)
51			if id != pid:
52				print "WRONG ECHO REPLY ID"
53				exit(2)
54			data=a.payload.payload.data
55			print "payload=%s" % (data)
56			if data == payload:
57				break
58			print "PAYLOAD!=%s" % (payload)
59			exit(1)
60	else:
61		print "NO ECHO REPLY"
62		exit(2)
63