1#!/usr/local/bin/python2.7
2# send fragments of a large packet that has to be refragmented by reflector
3
4# |--------|
5#          |------------------|
6#                              ...
7#                                 |------------------|
8#                                                    |----|
9
10import os
11from addr import *
12from scapy.all import *
13
14pid=os.getpid()
15payload=100 * "ABCDEFGHIJKLMNOP"
16packet=IPv6(src=SRC_OUT6, dst=DST_IN6)/ICMPv6EchoRequest(id=pid, data=payload)
17request_cksum=ICMPv6Unknown(str(packet.payload)).cksum
18print "request cksum=%#x" % (request_cksum)
19frag=[]
20frag.append(IPv6ExtHdrFragment(nh=58, id=pid, m=1)/str(packet)[40:56])
21offset=2
22chunk=4
23while 40+8*(offset+chunk) < len(payload):
24	frag.append(IPv6ExtHdrFragment(nh=58, id=pid, offset=offset, m=1)/
25	    str(packet)[40+(8*offset):40+8*(offset+chunk)])
26	offset+=chunk
27frag.append(IPv6ExtHdrFragment(nh=58, id=pid, offset=offset)/
28    str(packet)[40+(8*offset):])
29eth=[]
30for f in frag:
31	pkt=IPv6(src=SRC_OUT6, dst=DST_IN6)/f
32	eth.append(Ether(src=SRC_MAC, dst=DST_MAC)/pkt)
33
34if os.fork() == 0:
35	time.sleep(1)
36	sendp(eth, iface=SRC_IF)
37	os._exit(0)
38
39ans=sniff(iface=SRC_IF, timeout=3, filter=
40    "ip6 and src "+DST_IN6+" and dst "+SRC_OUT6+" and proto ipv6-frag")
41for a in ans:
42	if a and a.type == ETH_P_IPV6 and \
43	    ipv6nh[a.payload.nh] == 'Fragment Header' and \
44	    a.payload.payload.offset == 0 and \
45	    ipv6nh[a.payload.payload.nh] == 'ICMPv6' and \
46	    icmp6types[a.payload.payload.payload.type] == 'Echo Reply':
47		id=a.payload.payload.payload.id
48		print "id=%#x" % (id)
49		if id != pid:
50			print "WRONG ECHO REPLY ID"
51			exit(2)
52		reply_cksum=a.payload.payload.payload.cksum
53		print "reply cksum=%#x" % (reply_cksum)
54		# change request checksum incrementaly and check with reply
55		diff_cksum=~(~reply_cksum+~(~request_cksum+~0x8000+0x8100))
56		if  diff_cksum != -1:
57			print "CHECKSUM ERROR diff cksum=%#x" % (diff_cksum)
58			exit(1)
59		exit(0)
60print "NO ECHO REPLY"
61exit(2)
62