1#!/usr/local/bin/python2.7 2# check wether path mtu to dst is 1300 3 4import os 5import threading 6from addr import * 7from scapy.all import * 8 9# work around the broken sniffing of packages with bad checksum 10#a=srp1(eth, iface=SRC_IF, timeout=2) 11class Sniff1(threading.Thread): 12 filter = None 13 captured = None 14 packet = None 15 def run(self): 16 self.captured = sniff(iface=SRC_IF, filter=self.filter, 17 count=1, timeout=3) 18 if self.captured: 19 self.packet = self.captured[0] 20 21dstaddr=sys.argv[1] 22eid=os.getpid() & 0xffff 23hdr=IPv6(src=SRC_OUT6, dst=dstaddr)/ICMPv6EchoRequest(id=eid) 24payload="a" * (1400 - len(str(hdr))) 25ip=hdr/payload 26eth=Ether(src=SRC_MAC, dst=PF_MAC)/ip 27 28sniffer = Sniff1(); 29# pcap cannot access icmp6, check for packet too big, avoid neighbor discovery 30sniffer.filter = "ip6 and dst %s and icmp6 and ip6[40] = 2 and ip6[41] = 0" \ 31 % SRC_OUT6 32sniffer.start() 33time.sleep(1) 34sendp(eth, iface=SRC_IF) 35sniffer.join(timeout=5) 36a = sniffer.packet 37 38if a is None: 39 print "no packet sniffed" 40 exit(2) 41if a and a.type == ETH_P_IPV6 and \ 42 ipv6nh[a.payload.nh] == 'ICMPv6' and \ 43 icmp6types[a.payload.payload.type] == 'Packet too big': 44 mtu=a.payload.payload.mtu 45 print "mtu=%d" % (mtu) 46 if mtu == 1300: 47 exit(0) 48 print "MTU!=1300" 49 exit(1) 50print "MTU=UNKNOWN" 51exit(2) 52