1#!/usr/local/bin/python2.7 2# check wether path mtu to dst is as expected 3 4import os 5from addr import * 6from scapy.all import * 7 8# usage: ping6_mtu src dst size icmp6-size 9 10srcaddr=sys.argv[1] 11dstaddr=sys.argv[2] 12size=int(sys.argv[3]) 13expect=int(sys.argv[4]) 14pid=os.getpid() 15hdr=IPv6(src=srcaddr, dst=dstaddr)/ICMPv6EchoRequest(id=pid) 16payload="a" * (size - len(str(hdr))) 17ip=hdr/payload 18iplen=IPv6(str(ip)).plen 19eth=Ether(src=SRC_MAC, dst=PF_MAC)/ip 20 21# work around the broken sniffing of packages with bad checksum 22#a=srp1(eth, iface=SRC_IF, timeout=2) 23if os.fork() == 0: 24 time.sleep(1) 25 sendp(eth, iface=SRC_IF) 26 os._exit(0) 27ans=sniff(iface=SRC_IF, timeout=3, filter= 28 "ip6 and dst "+srcaddr+" and icmp6") 29if len(ans) == 0: 30 print "no packet sniffed" 31 exit(2) 32a=ans[0] 33 34if a and a.type == ETH_P_IPV6 and \ 35 ipv6nh[a.payload.nh] == 'ICMPv6' and \ 36 icmp6types[a.payload.payload.type] == 'Packet too big': 37 mtu=a.payload.payload.mtu 38 print "mtu=%d" % (mtu) 39 if mtu != expect: 40 print "MTU!=%d" % (expect) 41 exit(1) 42 len=a.payload.payload.payload.plen 43 if len != iplen: 44 print "IPv6 plen %d!=%d" % (len, iplen) 45 exit(1) 46 exit(0) 47print "MTU=UNKNOWN" 48exit(2) 49