1#!/usr/local/bin/python2.7 2 3import os 4import string 5import random 6from addr import * 7from scapy.all import * 8 9e=Ether(src=LOCAL_MAC, dst=REMOTE_MAC) 10ip6=IPv6(src=FAKE_NET_ADDR6, dst=REMOTE_ADDR6) 11port=os.getpid() & 0xffff 12 13print "Send UDP packet with 1400 octets payload, receive echo." 14data=''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + 15 string.digits) for _ in range(1400)) 16udp=UDP(sport=port, dport='echo')/data 17echo=srp1(e/ip6/udp, iface=LOCAL_IF, timeout=5) 18 19print "Send ICMP6 packet too big packet with MTU 1300." 20icmp6=ICMPv6PacketTooBig(mtu=1300)/echo.payload 21sendp(e/IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/icmp6, iface=LOCAL_IF) 22 23print "Clear route cache at echo socket by sending from different address." 24sendp(e/IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/udp, iface=LOCAL_IF) 25 26print "Path MTU discovery will send UDP fragment with maximum length 1300." 27# srp1 cannot be used, fragment answer will not match on outgoing udp packet 28if os.fork() == 0: 29 time.sleep(1) 30 sendp(e/ip6/udp, iface=LOCAL_IF) 31 os._exit(0) 32 33ans=sniff(iface=LOCAL_IF, timeout=3, filter= 34 "ip6 and src "+ip6.dst+" and dst "+ip6.src+" and proto ipv6-frag") 35 36for a in ans: 37 fh=a.payload.payload 38 if fh.offset != 0 or fh.nh != (ip6/udp).nh: 39 continue 40 uh=fh.payload 41 if uh.sport != udp.dport or uh.dport != udp.sport: 42 continue 43 frag=a 44 break 45else: 46 print "ERROR: no matching IPv6 fragment UDP answer found" 47 exit(1) 48 49print "UDP echo has IPv6 and UDP header, so expected payload len is 1448" 50elen = echo.plen + len(IPv6()) 51print "elen=%d" % elen 52if elen != 1448: 53 print "ERROR: UDP echo paylod len is %d, expected 1448." % elen 54 exit(1) 55 56print "Fragments contain multiple of 8 octets, so expected len is 1296" 57flen = frag.plen + len(IPv6()) 58print "flen=%d" % flen 59if flen != 1296: 60 print "ERROR: UDP fragment len is %d, expected 1296." % flen 61 exit(1) 62 63exit(0) 64