xref: /openbsd-src/regress/sys/net/pf_forward/ping6_mtu.py (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
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() & 0xffff
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	iip=a.payload.payload.payload
43	iiplen=iip.plen
44	if iiplen != iplen:
45		print "inner IPv6 plen %d!=%d" % (iiplen, iplen)
46		exit(1)
47	isrc=iip.src
48	if isrc != srcaddr:
49		print "inner IPv6 src %d!=%d" % (isrc, srcaddr)
50		exit(1)
51	idst=iip.dst
52	if idst != dstaddr:
53		print "inner IPv6 dst %d!=%d" % (idst, dstaddr)
54		exit(1)
55	exit(0)
56print "MTU=UNKNOWN"
57exit(2)
58