summaryrefslogtreecommitdiff
path: root/regress/sys
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2017-01-18 19:27:00 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2017-01-18 19:27:00 +0000
commita011092ef38ac3ac057181567c0037a295149930 (patch)
tree3b4d604547133ead5a4976f4e5ad9a72272010e1 /regress/sys
parentbde2df117499cb77cc0553de690dcdabdcc3c0b3 (diff)
Add tests that generate IPv6 atomic fragments for UDP and TCP by
sending an ICMP6 too big packet with MTU 1272.
Diffstat (limited to 'regress/sys')
-rw-r--r--regress/sys/netinet/pmtu/Makefile13
-rwxr-xr-xregress/sys/netinet/pmtu/tcp_atomicfrag6.py78
-rwxr-xr-xregress/sys/netinet/pmtu/tcp_connect.py2
-rwxr-xr-xregress/sys/netinet/pmtu/tcp_connect6.py2
-rwxr-xr-xregress/sys/netinet/pmtu/udp_atomicfrag6.py78
-rwxr-xr-xregress/sys/netinet/pmtu/udp_echo6.py5
6 files changed, 174 insertions, 4 deletions
diff --git a/regress/sys/netinet/pmtu/Makefile b/regress/sys/netinet/pmtu/Makefile
index ddd6c470492..6c0193d580e 100644
--- a/regress/sys/netinet/pmtu/Makefile
+++ b/regress/sys/netinet/pmtu/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.7 2016/11/09 12:43:36 bluhm Exp $
+# $OpenBSD: Makefile,v 1.8 2017/01/18 19:26:59 bluhm Exp $
# The following ports must be installed:
#
@@ -146,6 +146,17 @@ run-regress-gateway6: run-regress-udp6
grep -q 'flags: <UP,GATEWAY,HOST,DYNAMIC,DONE>' pmtu.route
${SUDO} ${PYTHON}udp_echo6.py
+TARGETS += tcpfrag6 udpfrag6
+run-regress-tcpfrag6: addr.py reset-route6
+ @echo '\n======== $@ ========'
+ @echo Send ICMP6 and try to trigger a short TCP segment
+ ${SUDO} ${PYTHON}tcp_atomicfrag6.py
+run-regress-udpfrag6: addr.py reset-route6
+ @echo '\n======== $@ ========'
+ @echo Send ICMP6 and try to trigger an atomic UDP IPv6 fragment
+ ${SUDO} ${PYTHON}udp_atomicfrag6.py
+
+
REGRESS_TARGETS = ${TARGETS:S/^/run-regress-/}
CLEANFILES += addr.py *.pyc *.log *.route
diff --git a/regress/sys/netinet/pmtu/tcp_atomicfrag6.py b/regress/sys/netinet/pmtu/tcp_atomicfrag6.py
new file mode 100755
index 00000000000..d0646b544d5
--- /dev/null
+++ b/regress/sys/netinet/pmtu/tcp_atomicfrag6.py
@@ -0,0 +1,78 @@
+#!/usr/local/bin/python2.7
+
+import os
+from addr import *
+from scapy.all import *
+
+e=Ether(src=LOCAL_MAC, dst=REMOTE_MAC)
+ip6=IPv6(src=FAKE_NET_ADDR6, dst=REMOTE_ADDR6)
+port=os.getpid() & 0xffff
+
+print "Send SYN packet, receive SYN+ACK."
+syn=TCP(sport=port, dport='chargen', seq=1, flags='S', window=(2**16)-1)
+synack=srp1(e/ip6/syn, iface=LOCAL_IF, timeout=5)
+
+if synack is None:
+ print "ERROR: no SYN+ACK from chargen server received"
+ exit(1)
+
+print "Send ACK packet, receive chargen data."
+ack=TCP(sport=synack.dport, dport=synack.sport, seq=2, flags='A',
+ ack=synack.seq+1, window=(2**16)-1)
+data=srp1(e/ip6/ack, iface=LOCAL_IF, timeout=5)
+
+if data is None:
+ print "ERROR: no data from chargen server received"
+ exit(1)
+
+print "Fill our receive buffer."
+time.sleep(1)
+
+print "Send ICMP6 packet too big packet with MTU 1272."
+icmp6=ICMPv6PacketTooBig(mtu=1272)/data.payload
+sendp(e/IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/icmp6, iface=LOCAL_IF)
+
+print "Path MTU discovery will resend first data with length 1272."
+# srp1 cannot be used, fragment answer will not match on outgoing udp packet
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(e/ip6/ack, iface=LOCAL_IF)
+ os._exit(0)
+
+ans=sniff(iface=LOCAL_IF, timeout=3, filter=
+ "ip6 and src "+ip6.dst+" and dst "+ip6.src+" and proto ipv6-frag")
+
+for a in ans:
+ fh=a.payload.payload
+ if fh.offset != 0 or fh.nh != (ip6/syn).nh:
+ continue
+ th=fh.payload
+ if th.sport != syn.dport or th.dport != syn.sport:
+ continue
+ frag=a
+ break
+else:
+ print "ERROR: no fragement retransmit from chargen server received"
+ exit(1)
+
+print "Cleanup the other's socket with a reset packet."
+rst=TCP(sport=synack.dport, dport=synack.sport, seq=2, flags='AR',
+ ack=synack.seq+1)
+sendp(e/ip6/rst, iface=LOCAL_IF)
+
+if frag.offset != 0:
+ print "ERROR: TCP fragment is not atomic, offset is %d." % frag.offset
+ exit(1)
+
+if frag.m != 0:
+ print "ERROR: TCP fragment is not atomic, more fragment bit is set."
+ exit(1)
+
+print "Atomic fragment contains 8 octet header, so expected len is 1280"
+flen = frag.plen + len(IPv6())
+print "flen=%d" % flen
+if flen != 1280:
+ print "ERROR: TCP atomic fragment len is %d, expected 1280." % flen
+ exit(1)
+
+exit(0)
diff --git a/regress/sys/netinet/pmtu/tcp_connect.py b/regress/sys/netinet/pmtu/tcp_connect.py
index 2e3ea22e02e..0ba209800a1 100755
--- a/regress/sys/netinet/pmtu/tcp_connect.py
+++ b/regress/sys/netinet/pmtu/tcp_connect.py
@@ -15,7 +15,7 @@ if synack is None:
print "ERROR: no SYN+ACK from chargen server received"
exit(1)
-print "Send ack packet, receive chargen data."
+print "Send ACK packet, receive chargen data."
ack=TCP(sport=synack.dport, dport=synack.sport, seq=2, flags='A',
ack=synack.seq+1, window=(2**16)-1)
data=sr1(ip/ack, iface=LOCAL_IF, timeout=5)
diff --git a/regress/sys/netinet/pmtu/tcp_connect6.py b/regress/sys/netinet/pmtu/tcp_connect6.py
index dec42858368..dc0c4ef0690 100755
--- a/regress/sys/netinet/pmtu/tcp_connect6.py
+++ b/regress/sys/netinet/pmtu/tcp_connect6.py
@@ -16,7 +16,7 @@ if synack is None:
print "ERROR: no SYN+ACK from chargen server received"
exit(1)
-print "Send ack packet, receive chargen data."
+print "Send ACK packet, receive chargen data."
ack=TCP(sport=synack.dport, dport=synack.sport, seq=2, flags='A',
ack=synack.seq+1, window=(2**16)-1)
data=srp1(e/ip6/ack, iface=LOCAL_IF, timeout=5)
diff --git a/regress/sys/netinet/pmtu/udp_atomicfrag6.py b/regress/sys/netinet/pmtu/udp_atomicfrag6.py
new file mode 100755
index 00000000000..ef25af79af5
--- /dev/null
+++ b/regress/sys/netinet/pmtu/udp_atomicfrag6.py
@@ -0,0 +1,78 @@
+#!/usr/local/bin/python2.7
+
+import os
+import string
+import random
+from addr import *
+from scapy.all import *
+
+e=Ether(src=LOCAL_MAC, dst=REMOTE_MAC)
+ip6=IPv6(src=FAKE_NET_ADDR6, dst=REMOTE_ADDR6)
+port=os.getpid() & 0xffff
+# inetd ignores packets from privileged port or nfs
+if port < 1024 or port == 2049:
+ port+=1024
+
+print "Send UDP packet with 1200 octets payload, receive echo."
+data=''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase +
+ string.digits) for _ in range(1200))
+udp=UDP(sport=port, dport='echo')/data
+echo=srp1(e/ip6/udp, iface=LOCAL_IF, timeout=5)
+
+if echo is None:
+ print "ERROR: no UDP answer from echo server received"
+ exit(1)
+
+print "Send ICMP6 packet too big packet with MTU 1272."
+icmp6=ICMPv6PacketTooBig(mtu=1272)/echo.payload
+sendp(e/IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/icmp6, iface=LOCAL_IF)
+
+print "Clear route cache at echo socket by sending from different address."
+sendp(e/IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/udp, iface=LOCAL_IF)
+
+print "Path MTU discovery will send UDP atomic fragment with length 1256."
+# srp1 cannot be used, fragment answer will not match on outgoing udp packet
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(e/ip6/udp, iface=LOCAL_IF)
+ os._exit(0)
+
+ans=sniff(iface=LOCAL_IF, timeout=3, filter=
+ "ip6 and src "+ip6.dst+" and dst "+ip6.src+" and proto ipv6-frag")
+
+for a in ans:
+ fh=a.payload.payload
+ if fh.offset != 0 or fh.nh != (ip6/udp).nh:
+ continue
+ uh=fh.payload
+ if uh.sport != udp.dport or uh.dport != udp.sport:
+ continue
+ frag=a
+ break
+else:
+ print "ERROR: no matching IPv6 fragment UDP answer found"
+ exit(1)
+
+if frag.offset != 0:
+ print "ERROR: TCP fragment is not atomic, offset is %d." % frag.offset
+ exit(1)
+
+if frag.m != 0:
+ print "ERROR: TCP fragment is not atomic, more fragment bit is set."
+ exit(1)
+
+print "UDP echo has IPv6 and UDP header, so expected payload len is 1248"
+elen = echo.plen + len(IPv6())
+print "elen=%d" % elen
+if elen != 1248:
+ print "ERROR: UDP echo payload len is %d, expected 1248." % elen
+ exit(1)
+
+print "Atomic fragment contains 8 octet header, so expected len is 1256"
+flen = frag.plen + len(IPv6())
+print "flen=%d" % flen
+if flen != 1256:
+ print "ERROR: UDP atomic fragment len is %d, expected 1256." % flen
+ exit(1)
+
+exit(0)
diff --git a/regress/sys/netinet/pmtu/udp_echo6.py b/regress/sys/netinet/pmtu/udp_echo6.py
index 55f86c37072..72b815baa94 100755
--- a/regress/sys/netinet/pmtu/udp_echo6.py
+++ b/regress/sys/netinet/pmtu/udp_echo6.py
@@ -9,6 +9,9 @@ from scapy.all import *
e=Ether(src=LOCAL_MAC, dst=REMOTE_MAC)
ip6=IPv6(src=FAKE_NET_ADDR6, dst=REMOTE_ADDR6)
port=os.getpid() & 0xffff
+# inetd ignores packets from privileged port or nfs
+if port < 1024 or port == 2049:
+ port+=1024
print "Send UDP packet with 1400 octets payload, receive echo."
data=''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase +
@@ -54,7 +57,7 @@ print "UDP echo has IPv6 and UDP header, so expected payload len is 1448"
elen = echo.plen + len(IPv6())
print "elen=%d" % elen
if elen != 1448:
- print "ERROR: UDP echo paylod len is %d, expected 1448." % elen
+ print "ERROR: UDP echo payload len is %d, expected 1448." % elen
exit(1)
print "Fragments contain multiple of 8 octets, so expected len is 1296"