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