summaryrefslogtreecommitdiff
path: root/regress
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2018-09-10 13:00:59 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2018-09-10 13:00:59 +0000
commit3f0991cd01030db6b0c863f89cb29a1ac3f4597b (patch)
tree22b193e33a89a3bc08bcc811347a92a976181e5b /regress
parentb32233bbbcde302220cc5f0e49771a864c6b2718 (diff)
Send many small fragments that exceed the pf reassembly queue limit.
Diffstat (limited to 'regress')
-rw-r--r--regress/sys/netinet/frag/Makefile7
-rw-r--r--regress/sys/netinet/frag/frag_queuelimit.py71
-rw-r--r--regress/sys/netinet6/frag6/Makefile7
-rw-r--r--regress/sys/netinet6/frag6/frag6_queuelimit.py71
4 files changed, 154 insertions, 2 deletions
diff --git a/regress/sys/netinet/frag/Makefile b/regress/sys/netinet/frag/Makefile
index 6c85de1867c..2cd0c9ef306 100644
--- a/regress/sys/netinet/frag/Makefile
+++ b/regress/sys/netinet/frag/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.3 2018/08/30 19:34:37 bluhm Exp $
+# $OpenBSD: Makefile,v 1.4 2018/09/10 13:00:58 bluhm Exp $
# The following ports must be installed:
#
@@ -112,6 +112,11 @@ run-regress-stack-frag_mf1end.py:
# the stack allows fragments with MF together with fragments without MF
@echo DISABLED
+run-regress-stack-frag_queuelimit.py:
+ @echo '\n======== $@ ========'
+ # the stack does not limit the amount of fragments during reassembly
+ @echo DISABLED
+
.for sp in stack pf
# Ping all addresses. This ensures that the ip addresses are configured
diff --git a/regress/sys/netinet/frag/frag_queuelimit.py b/regress/sys/netinet/frag/frag_queuelimit.py
new file mode 100644
index 00000000000..2edf4b6d3cf
--- /dev/null
+++ b/regress/sys/netinet/frag/frag_queuelimit.py
@@ -0,0 +1,71 @@
+#!/usr/local/bin/python2.7
+
+print "drop too long fragment queue, reassemble less fragments"
+
+# |----|
+# |----|
+# |----|
+# ... ...
+# |----|
+
+import os
+from addr import *
+from scapy.all import *
+
+pid=os.getpid()
+eid=pid & 0xffff
+payload="ABCDEFGHIJKLMNOP" * 70
+frag=[]
+fid=pid & 0xffff
+# send packets with 65 and 64 fragments
+for max in (64, 63):
+ eid = ~eid & 0xffff
+ packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \
+ ICMP(type='echo-request', id=eid)/payload
+ fid = ~fid & 0xffff
+ for i in range(max):
+ frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
+ frag=i, flags='MF')/str(packet)[20+i*8:20+(i+1)*8])
+ frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
+ frag=max)/str(packet)[20+max*8:])
+eth=[]
+for f in frag:
+ eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f)
+
+child = os.fork()
+if child == 0:
+ time.sleep(1)
+ for e in eth:
+ sendp(e, iface=LOCAL_IF)
+ time.sleep(0.001)
+ os._exit(0)
+
+ans=sniff(iface=LOCAL_IF, timeout=6, filter=
+ "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp")
+os.kill(child, 15)
+os.wait()
+
+reply=False
+for a in ans:
+ if a and a.type == ETH_P_IP and \
+ a.payload.proto == 1 and \
+ a.payload.frag == 0 and a.payload.flags == 0 and \
+ icmptypes[a.payload.payload.type] == 'echo-reply':
+ id=a.payload.payload.id
+ print "id=%#x" % (id)
+ if id == ~eid & 0xffff:
+ print "ECHO REPLY FROM 65 FRAGMENTS"
+ exit(1)
+ if id != eid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ data=a.payload.payload.payload.load
+ print "payload=%s" % (data)
+ if data != payload:
+ print "PAYLOAD!=%s" % (payload)
+ exit(2)
+ reply=True
+if not reply:
+ print "NO ECHO REPLY FROM 64 FRAGMENTS"
+ exit(1)
+exit(0)
diff --git a/regress/sys/netinet6/frag6/Makefile b/regress/sys/netinet6/frag6/Makefile
index 40432839443..06f5ebae0fb 100644
--- a/regress/sys/netinet6/frag6/Makefile
+++ b/regress/sys/netinet6/frag6/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.23 2017/11/14 15:30:35 bluhm Exp $
+# $OpenBSD: Makefile,v 1.24 2018/09/10 13:00:58 bluhm Exp $
# The following ports must be installed:
#
@@ -97,6 +97,11 @@ stamp-pf: addr.py pf.conf
REGRESS_TARGETS =
FRAG6_SCRIPTS !!= cd ${.CURDIR} && ls -1 frag6*.py
+run-regress-stack-frag6_queuelimit.py:
+ @echo '\n======== $@ ========'
+ # the stack does not limit the amount of fragments during reassembly
+ @echo DISABLED
+
.for sp in stack pf
# Ping all addresses. This ensures that the ip addresses are configured
diff --git a/regress/sys/netinet6/frag6/frag6_queuelimit.py b/regress/sys/netinet6/frag6/frag6_queuelimit.py
new file mode 100644
index 00000000000..8f14522f6bd
--- /dev/null
+++ b/regress/sys/netinet6/frag6/frag6_queuelimit.py
@@ -0,0 +1,71 @@
+#!/usr/local/bin/python2.7
+
+print "drop too long fragment queue, reassemble less fragments"
+
+# |----|
+# |----|
+# |----|
+# ... ...
+# |----|
+
+import os
+from addr import *
+from scapy.all import *
+
+pid=os.getpid()
+eid=pid & 0xffff
+payload="ABCDEFGHIJKLMNOP" * 70
+frag=[]
+fid=pid & 0xffffffff
+# send packets with 65 and 64 fragments
+for max in (64, 63):
+ eid = ~eid & 0xffff
+ packet=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/ \
+ ICMPv6EchoRequest(id=eid, data=payload)
+ fid = ~fid & 0xffffffff
+ for i in range(max):
+ frag.append(IPv6ExtHdrFragment(nh=58, id=fid, m=1,
+ offset=i)/str(packet)[40+i*8:40+(i+1)*8])
+ frag.append(IPv6ExtHdrFragment(nh=58, id=fid,
+ offset=max)/str(packet)[40+max*8:])
+eth=[]
+for f in frag:
+ pkt=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/f
+ eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/pkt)
+
+child = os.fork()
+if child == 0:
+ time.sleep(1)
+ for e in eth:
+ sendp(e, iface=LOCAL_IF)
+ time.sleep(0.001)
+ os._exit(0)
+
+ans=sniff(iface=LOCAL_IF, timeout=6, filter=
+ "ip6 and src "+REMOTE_ADDR6+" and dst "+LOCAL_ADDR6+" and icmp6")
+os.kill(child, 15)
+os.wait()
+
+reply=False
+for a in ans:
+ if a and a.type == ETH_P_IPV6 and \
+ ipv6nh[a.payload.nh] == 'ICMPv6' and \
+ icmp6types[a.payload.payload.type] == 'Echo Reply':
+ id=a.payload.payload.id
+ print "id=%#x" % (id)
+ if id == ~eid & 0xffff:
+ print "ECHO REPLY FROM 65 FRAGMENTS"
+ exit(1)
+ if id != eid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ data=a.payload.payload.data
+ print "payload=%s" % (data)
+ if data != payload:
+ print "PAYLOAD!=%s" % (payload)
+ exit(2)
+ reply=True
+if not reply:
+ print "NO ECHO REPLY FROM 64 FRAGMENTS"
+ exit(1)
+exit(0)