1#!/usr/local/bin/python3 2 3print("drop too long fragment queue, reassemble less fragments") 4 5# |----| 6# |----| 7# |----| 8# ... ... 9# |----| 10 11import os 12from addr import * 13from scapy.all import * 14 15pid=os.getpid() 16eid=pid & 0xffff 17payload=b"ABCDEFGHIJKLMNOP" * 70 18frag=[] 19fid=pid & 0xffffffff 20# send packets with 65 and 64 fragments 21for max in (64, 63): 22 eid = ~eid & 0xffff 23 packet=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/ \ 24 ICMPv6EchoRequest(id=eid, data=payload) 25 fid = ~fid & 0xffffffff 26 for i in range(max): 27 frag.append(IPv6ExtHdrFragment(nh=58, id=fid, m=1, 28 offset=i)/bytes(packet)[40+i*8:40+(i+1)*8]) 29 frag.append(IPv6ExtHdrFragment(nh=58, id=fid, 30 offset=max)/bytes(packet)[40+max*8:]) 31eth=[] 32for f in frag: 33 pkt=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/f 34 eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/pkt) 35 36child = os.fork() 37if child == 0: 38 time.sleep(1) 39 for e in eth: 40 sendp(e, iface=LOCAL_IF) 41 time.sleep(0.001) 42 os._exit(0) 43 44ans=sniff(iface=LOCAL_IF, timeout=6, filter= 45 "ip6 and src "+REMOTE_ADDR6+" and dst "+LOCAL_ADDR6+" and icmp6") 46os.kill(child, 15) 47os.wait() 48 49reply=False 50for a in ans: 51 if a and a.type == ETH_P_IPV6 and \ 52 ipv6nh[a.payload.nh] == 'ICMPv6' and \ 53 icmp6types[a.payload.payload.type] == 'Echo Reply': 54 id=a.payload.payload.id 55 print("id=%#x" % (id)) 56 if id == ~eid & 0xffff: 57 print("ECHO REPLY FROM 65 FRAGMENTS") 58 exit(1) 59 if id != eid: 60 print("WRONG ECHO REPLY ID") 61 exit(2) 62 data=a.payload.payload.data 63 print("payload=%s" % (data)) 64 if data != payload: 65 print("PAYLOAD!=%s" % (payload)) 66 exit(2) 67 reply=True 68if not reply: 69 print("NO ECHO REPLY FROM 64 FRAGMENTS") 70 exit(1) 71print("echo reply from 64 fragments") 72exit(0) 73