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