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