xref: /openbsd-src/regress/sys/netinet/pmtu/tcp_connect.py (revision ae3cb403620ab940fbaabb3055fac045a63d56b7)
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