1*85c0d959Sbluhm#!/usr/local/bin/python3 20d0cafa0Sbluhm# check wether path mtu to dst is as expected 30d0cafa0Sbluhm 40d0cafa0Sbluhmimport os 50d0cafa0Sbluhmfrom addr import * 60d0cafa0Sbluhmfrom scapy.all import * 70d0cafa0Sbluhm 85004ddd2Sbluhm# usage: ping_mtu src dst size icmp-size 95004ddd2Sbluhm 105004ddd2Sbluhmsrcaddr=sys.argv[1] 115004ddd2Sbluhmdstaddr=sys.argv[2] 125004ddd2Sbluhmsize=int(sys.argv[3]) 135004ddd2Sbluhmexpect=int(sys.argv[4]) 149ae5678bSbluhmeid=os.getpid() & 0xffff 159ae5678bSbluhmhdr=IP(flags="DF", src=srcaddr, dst=dstaddr)/ICMP(type='echo-request', id=eid) 16*85c0d959Sbluhmpayload="a" * (size - len(bytes(hdr))) 175004ddd2Sbluhmip=hdr/payload 18*85c0d959Sbluhmiplen=IP(bytes(ip)).len 19621b42f7Sbluhmeth=Ether(src=SRC_MAC, dst=PF_MAC)/ip 20621b42f7Sbluhma=srp1(eth, iface=SRC_IF, timeout=2) 215004ddd2Sbluhm 221ca2c44dSbluhmif a is None: 23*85c0d959Sbluhm print("no packet sniffed") 241ca2c44dSbluhm exit(2) 250d0cafa0Sbluhmif a and a.payload.payload.type==3 and a.payload.payload.code==4: 267553dc43Sbluhm mtu=a.payload.payload.nexthopmtu 27*85c0d959Sbluhm print("mtu=%d" % (mtu)) 28621b42f7Sbluhm if mtu != expect: 29*85c0d959Sbluhm print("MTU!=%d" % (expect)) 300d0cafa0Sbluhm exit(1) 31a2cb595eSbluhm iip=a.payload.payload.payload 32a2cb595eSbluhm iiplen=iip.len 33a2cb595eSbluhm if iiplen != iplen: 34*85c0d959Sbluhm print("inner IP len %d!=%d" % (iiplen, iplen)) 35a2cb595eSbluhm exit(1) 36a2cb595eSbluhm isrc=iip.src 37a2cb595eSbluhm if isrc != srcaddr: 38*85c0d959Sbluhm print("inner IP src %d!=%d" % (isrc, srcaddr)) 39a2cb595eSbluhm exit(1) 40a2cb595eSbluhm idst=iip.dst 41a2cb595eSbluhm if idst != dstaddr: 42*85c0d959Sbluhm print("inner IP dst %d!=%d" % (idst, dstaddr)) 43621b42f7Sbluhm exit(1) 44621b42f7Sbluhm exit(0) 45*85c0d959Sbluhmprint("MTU=UNKNOWN") 460d0cafa0Sbluhmexit(2) 47