1#!/usr/local/bin/python2.7 2 3import os 4import threading 5from addr import * 6from scapy.all import * 7 8class Sniff1(threading.Thread): 9 filter = None 10 captured = None 11 packet = None 12 def __init__(self): 13 # clear packets buffered by scapy bpf 14 sniff(iface=LOCAL_IF, timeout=1) 15 super(Sniff1, self).__init__() 16 def run(self): 17 self.captured = sniff(iface=LOCAL_IF, filter=self.filter, 18 count=1, timeout=3) 19 if self.captured: 20 self.packet = self.captured[0] 21 22ip=IP(src=FAKE_NET_ADDR, dst=REMOTE_ADDR) 23tport=os.getpid() & 0xffff 24 25print "Send SYN packet, receive SYN+ACK." 26syn=TCP(sport=tport, dport='chargen', seq=1, flags='S', window=(2**16)-1) 27synack=sr1(ip/syn, iface=LOCAL_IF, timeout=5) 28 29if synack is None: 30 print "ERROR: no SYN+ACK from chargen server received" 31 exit(1) 32 33print "Send ACK packet, receive chargen data." 34ack=TCP(sport=synack.dport, dport=synack.sport, seq=2, flags='A', 35 ack=synack.seq+1, window=(2**16)-1) 36data=sr1(ip/ack, iface=LOCAL_IF, timeout=5) 37 38if data is None: 39 print "ERROR: no data from chargen server received" 40 exit(1) 41 42print "Fill our receive buffer." 43time.sleep(1) 44 45# sr1 cannot be used, TCP data will not match outgoing ICMP packet 46sniffer = Sniff1() 47sniffer.filter = \ 48 "ip and src %s and tcp port %u and dst %s and tcp port %u" % \ 49 (ip.dst, syn.dport, ip.src, syn.sport) 50sniffer.start() 51time.sleep(1) 52 53print "Send ICMP fragmentation needed packet with MTU 1300." 54icmp=ICMP(type="dest-unreach", code="fragmentation-needed", 55 nexthopmtu=1300)/data 56send(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/icmp, iface=LOCAL_IF) 57 58print "Path MTU discovery will resend first data with length 1300." 59sniffer.join(timeout=5) 60ans = sniffer.packet 61 62if len(ans) == 0: 63 print "ERROR: no data retransmit from chargen server received" 64 exit(1) 65data=ans[0] 66 67print "Cleanup the other's socket with a reset packet." 68rst=TCP(sport=synack.dport, dport=synack.sport, seq=2, flags='AR', 69 ack=synack.seq+1) 70send(ip/rst, iface=LOCAL_IF) 71 72len = data.len 73print "len=%d" % len 74if len != 1300: 75 print "ERROR: TCP data packet len is %d, expected 1300." % len 76 exit(1) 77 78exit(0) 79