xref: /openbsd-src/regress/sys/netinet/pmtu/tcp_atomicfrag6.py (revision e7abe75af641bacab1663afa28052d03f1e67610)
1*e7abe75aSbluhm#!/usr/local/bin/python3
293a55b4aSbluhm
393a55b4aSbluhmimport os
42b21f7bdSbluhmimport threading
593a55b4aSbluhmfrom addr import *
693a55b4aSbluhmfrom scapy.all import *
793a55b4aSbluhm
82b21f7bdSbluhmclass Sniff(threading.Thread):
92b21f7bdSbluhm	filter = None
102b21f7bdSbluhm	captured = None
112b21f7bdSbluhm	packet = None
122b21f7bdSbluhm	def __init__(self):
132b21f7bdSbluhm		# clear packets buffered by scapy bpf
142b21f7bdSbluhm		sniff(iface=LOCAL_IF, timeout=1)
152b21f7bdSbluhm		super(Sniff, self).__init__()
162b21f7bdSbluhm	def run(self):
172b21f7bdSbluhm		self.captured = sniff(iface=LOCAL_IF, filter=self.filter,
182b21f7bdSbluhm		    timeout=3)
192b21f7bdSbluhm		if self.captured:
202b21f7bdSbluhm			self.packet = self.captured[0]
212b21f7bdSbluhm
2293a55b4aSbluhme=Ether(src=LOCAL_MAC, dst=REMOTE_MAC)
2393a55b4aSbluhmip6=IPv6(src=FAKE_NET_ADDR6, dst=REMOTE_ADDR6)
249ae5678bSbluhmtport=os.getpid() & 0xffff
2593a55b4aSbluhm
26*e7abe75aSbluhmprint("Send SYN packet, receive SYN+ACK.")
279ae5678bSbluhmsyn=TCP(sport=tport, dport='chargen', seq=1, flags='S', window=(2**16)-1)
2893a55b4aSbluhmsynack=srp1(e/ip6/syn, iface=LOCAL_IF, timeout=5)
2993a55b4aSbluhm
3093a55b4aSbluhmif synack is None:
31*e7abe75aSbluhm	print("ERROR: No SYN+ACK from chargen server received.")
3293a55b4aSbluhm	exit(1)
3393a55b4aSbluhm
34*e7abe75aSbluhmprint("Send ACK packet, receive chargen data.")
3593a55b4aSbluhmack=TCP(sport=synack.dport, dport=synack.sport, seq=2, flags='A',
3693a55b4aSbluhm    ack=synack.seq+1, window=(2**16)-1)
3793a55b4aSbluhmdata=srp1(e/ip6/ack, iface=LOCAL_IF, timeout=5)
3893a55b4aSbluhm
3993a55b4aSbluhmif data is None:
40*e7abe75aSbluhm	print("ERROR: No data from chargen server received.")
4193a55b4aSbluhm	exit(1)
4293a55b4aSbluhm
43*e7abe75aSbluhmprint("Fill our receive buffer.")
4493a55b4aSbluhmtime.sleep(1)
4593a55b4aSbluhm
462b21f7bdSbluhm# srp1 cannot be used, fragment answer will not match outgoing ICMP6 packet
472b21f7bdSbluhmsniffer = Sniff()
482b21f7bdSbluhmsniffer.filter = \
492b21f7bdSbluhm    "ip6 and src "+ip6.dst+" and dst "+ip6.src+" and proto ipv6-frag"
502b21f7bdSbluhmsniffer.start()
512b21f7bdSbluhmtime.sleep(1)
522b21f7bdSbluhm
53*e7abe75aSbluhmprint("Send ICMP6 packet too big packet with MTU 1272.")
5493a55b4aSbluhmicmp6=ICMPv6PacketTooBig(mtu=1272)/data.payload
55caed3289Sbluhmsendp(e/IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/icmp6, iface=LOCAL_IF)
5693a55b4aSbluhm
57*e7abe75aSbluhmprint("Path MTU discovery will not resend data, ICMP6 packet is ignored.")
582b21f7bdSbluhmsniffer.join(timeout=5)
5993a55b4aSbluhm
60*e7abe75aSbluhmprint("IPv6 atomic fragments must not be generated.")
6103da3b73Sbluhmfrag=None
622b21f7bdSbluhmfor a in sniffer.captured:
6393a55b4aSbluhm	fh=a.payload.payload
6493a55b4aSbluhm	if fh.offset != 0 or fh.nh != (ip6/syn).nh:
6593a55b4aSbluhm		continue
6693a55b4aSbluhm	th=fh.payload
6793a55b4aSbluhm	if th.sport != syn.dport or th.dport != syn.sport:
6893a55b4aSbluhm		continue
6993a55b4aSbluhm	frag=a
7093a55b4aSbluhm	break
7103da3b73Sbluhm
7203da3b73Sbluhmif frag is not None:
73*e7abe75aSbluhm	print("ERROR: Matching IPv6 fragment TCP answer found.")
7403da3b73Sbluhm	exit(1)
7503da3b73Sbluhm
76*e7abe75aSbluhmprint("Send ACK again to trigger retransmit.")
7703da3b73Sbluhmdata=srp1(e/ip6/ack, iface=LOCAL_IF, timeout=5)
7803da3b73Sbluhm
7903da3b73Sbluhmif data is None:
80*e7abe75aSbluhm	print("ERROR: No data retransmit from chargen server received.")
8193a55b4aSbluhm	exit(1)
8293a55b4aSbluhm
83*e7abe75aSbluhmprint("Cleanup the other's socket with a reset packet.")
8493a55b4aSbluhmrst=TCP(sport=synack.dport, dport=synack.sport, seq=2, flags='AR',
8593a55b4aSbluhm    ack=synack.seq+1)
8693a55b4aSbluhmsendp(e/ip6/rst, iface=LOCAL_IF)
8793a55b4aSbluhm
8803da3b73Sbluhmlen = data.plen + len(IPv6())
89*e7abe75aSbluhmprint("len=%d" % len)
9003da3b73Sbluhmif len != 1500:
91*e7abe75aSbluhm	print("ERROR: TCP data packet len is %d, expected 1500." % len)
9293a55b4aSbluhm	exit(1)
9393a55b4aSbluhm
9493a55b4aSbluhmexit(0)
95