1*ec1f834eSbluhm#!/usr/local/bin/python3 267cf0727Sbluhm# check wether path mtu to dst is as expected 367cf0727Sbluhm 467cf0727Sbluhmimport os 567cf0727Sbluhmimport threading 667cf0727Sbluhmfrom addr import * 767cf0727Sbluhmfrom scapy.all import * 867cf0727Sbluhm 967cf0727Sbluhm# 1067cf0727Sbluhm# we can not use scapy's sr() function as receive side 1167cf0727Sbluhm# ignores the packet we expect to see. Packet is ignored 1267cf0727Sbluhm# due to mismatching sequence numbers. 'bogus_syn' is using 1367cf0727Sbluhm# seq = 1000000, while response sent back by PF has ack, 1467cf0727Sbluhm# which fits regular session opened by 'syn'. 1567cf0727Sbluhm# 16de0a526bSbluhmclass Sniff1(threading.Thread): 17de0a526bSbluhm filter = None 1867cf0727Sbluhm captured = None 19de0a526bSbluhm packet = None 2067cf0727Sbluhm def run(self): 21de0a526bSbluhm self.captured = sniff(iface=LOCAL_IF, filter=self.filter, 22de0a526bSbluhm count=1, timeout=5) 23de0a526bSbluhm if self.captured: 24de0a526bSbluhm self.packet = self.captured[0] 2567cf0727Sbluhm 269ae5678bSbluhmtport=os.getpid() & 0xffff 2767cf0727Sbluhm 28de0a526bSbluhmip=IP(src=FAKE_NET_ADDR, dst=REMOTE_ADDR) 2967cf0727Sbluhm 30*ec1f834eSbluhmprint("Send SYN packet, receive SYN+ACK") 319ae5678bSbluhmsyn=TCP(sport=tport, dport='echo', seq=1, flags='S', window=(2**16)-1) 329ae5678bSbluhmsynack=sr1(ip/syn, iface=LOCAL_IF, timeout=5) 3305420020Sbluhm 349ae5678bSbluhmif synack is None: 35*ec1f834eSbluhm print("ERROR: no matching SYN+ACK packet received") 3605420020Sbluhm exit(1) 3767cf0727Sbluhm 38*ec1f834eSbluhmprint("Send ACK packet to finish handshake.") 399ae5678bSbluhmack=TCP(sport=synack.dport, dport=synack.sport, seq=2, flags='A', 409ae5678bSbluhm ack=synack.seq+1) 4167cf0727Sbluhmsend(ip/ack, iface=LOCAL_IF) 4267cf0727Sbluhm 43*ec1f834eSbluhmprint("Connection is established, send bogus SYN, expect challenge ACK") 449ae5678bSbluhmbogus_syn=TCP(sport=syn.sport, dport=syn.dport, seq=1000000, flags='S', 4567cf0727Sbluhm window=(2**16)-1) 46de0a526bSbluhmsniffer = Sniff1(); 479ae5678bSbluhmsniffer.filter = "src %s and tcp port %u and dst %s and tcp port %u " \ 489ae5678bSbluhm "and tcp[tcpflags] = tcp-ack" % (ip.dst, syn.dport, ip.src, syn.sport) 4967cf0727Sbluhmsniffer.start() 509a7ee091Sbluhmtime.sleep(1) 51de0a526bSbluhmsend(ip/bogus_syn, iface=LOCAL_IF) 52de0a526bSbluhmsniffer.join(timeout=7) 53de0a526bSbluhmchallenge_ack = sniffer.packet 5467cf0727Sbluhm 55de0a526bSbluhmif challenge_ack is None: 56*ec1f834eSbluhm print("ERROR: no matching ACK packet received") 5767cf0727Sbluhm exit(1) 5867cf0727Sbluhm 599ae5678bSbluhmif challenge_ack.getlayer(TCP).seq != (synack.seq + 1): 60*ec1f834eSbluhm print("ERROR: expecting seq %d got %d in challange ack" % \ 61*ec1f834eSbluhm (challenge_ack.getlayer(TCP).seq, (synack.seq + 1))) 6267cf0727Sbluhm exit(1) 6367cf0727Sbluhm 6467cf0727Sbluhmexit(0) 65