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