1#!/usr/local/bin/python2.7 2# check wether path mtu to dst is as expected 3 4import os 5import threading 6from addr import * 7from scapy.all import * 8 9# 10# we can not use scapy's sr() function as receive side 11# ignores the packet we expect to see. Packet is ignored 12# due to mismatching sequence numbers. 'bogus_syn' is using 13# seq = 1000000, while response sent back by PF has ack, 14# which fits regular session opened by 'syn'. 15# 16class Sniff1(threading.Thread): 17 filter = None 18 captured = None 19 packet = None 20 def run(self): 21 self.captured = sniff(iface=LOCAL_IF, filter=self.filter, 22 count=1, timeout=5) 23 if self.captured: 24 self.packet = self.captured[0] 25 26fake_port=os.getpid() & 0xffff 27 28ip=IP(src=FAKE_NET_ADDR, dst=REMOTE_ADDR) 29 30print "Send SYN packet, receive SYN+ACK" 31syn=TCP(sport=fake_port, dport='echo', seq=1, flags='S', window=(2**16)-1) 32synack=sr1(ip/syn, iface=LOCAL_IF, timeout=5) 33 34print "Send ACK packet to finish handshake." 35ack=TCP(sport=synack.dport, dport=synack.sport, seq=2, flags='A', 36 ack=synack.seq+1) 37send(ip/ack, iface=LOCAL_IF) 38 39print "Connection is established, send bogus SYN, expect challenge ACK" 40bogus_syn=TCP(sport=fake_port, dport='echo', seq=1000000, flags='S', 41 window=(2**16)-1) 42sniffer = Sniff1(); 43sniffer.filter = "src %s and tcp port echo and dst %s and tcp port %u " \ 44 "and tcp[tcpflags] = tcp-ack" % (REMOTE_ADDR, FAKE_NET_ADDR, fake_port) 45sniffer.start() 46time.sleep(1) 47send(ip/bogus_syn, iface=LOCAL_IF) 48sniffer.join(timeout=7) 49challenge_ack = sniffer.packet 50 51if challenge_ack is None: 52 print "ERROR: no matching ACK packet received" 53 exit(1) 54 55if challenge_ack.getlayer(TCP).seq != (synack.seq + 1): 56 print "ERROR: expecting seq %d got %d in challange ack" % \ 57 (challenge_ack.getlayer(TCP).seq, (synack.seq + 1)) 58 exit(1) 59 60exit(0) 61