1#!/usr/local/bin/python3 2 3print("ping6 fragments in total larger than IP maximum packet") 4 5# |---------| 6# |--------| 7# ... ... 8# |--------| 9 10import os 11from addr import * 12from scapy.all import * 13 14pid=os.getpid() 15eid=pid & 0xffff 16payload=b"ABCDEFGHIJKLMNOP" 17packet=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/ \ 18 ICMPv6EchoRequest(id=eid, data=4095*payload) 19plen=IPv6(raw(packet)).plen 20print("plen=%u" % (plen)) 21if plen != 0xfff8: 22 print("PLEN!=%u" % (0xfff8)) 23 exit(2) 24bytes=bytes(packet)+b"12345678" 25 26frag=[] 27fid=pid & 0xffffffff 28frag.append(IPv6ExtHdrFragment(nh=58, id=fid, m=1)/bytes[40:40+2**10]) 29off=2**7 30while off < 2**13: 31 frag.append(IPv6ExtHdrFragment(nh=58, id=fid, offset=off)/ \ 32 bytes[40+off*8:40+off*8+2**10]) 33 off+=2**7 34eth=[] 35for f in frag: 36 pkt=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/f 37 eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/pkt) 38 39if os.fork() == 0: 40 time.sleep(1) 41 sendp(eth, iface=LOCAL_IF) 42 os._exit(0) 43 44ans=sniff(iface=LOCAL_IF, timeout=3, filter= 45 "ip6 and src "+REMOTE_ADDR6+" and dst "+LOCAL_ADDR6+" and icmp6") 46for a in ans: 47 print("type %d" % (a.payload.payload.type)) 48 print("icmp %s" % (icmp6types[a.payload.payload.type])) 49 if a and a.type == ETH_P_IPV6 and \ 50 ipv6nh[a.payload.nh] == 'ICMPv6' and \ 51 icmp6types[a.payload.payload.type] == 'Parameter problem': 52 print("code=%u" % (a.payload.payload.code)) 53 # 0: 'erroneous header field encountered' 54 if a.payload.payload.code != 0: 55 print("WRONG PARAMETER PROBLEM CODE") 56 exit(1) 57 ptr=a.payload.payload.ptr 58 print("ptr=%u" % (ptr)) 59 # 42: sizeof IPv6 header + offset in fragment header 60 if ptr != 42: 61 print("PTR!=%u" % (ptr)) 62 exit(1) 63 exit(0) 64print("NO ICMP PARAMETER PROBLEM") 65exit(2) 66