summaryrefslogtreecommitdiff
path: root/regress
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2011-09-21 23:48:24 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2011-09-21 23:48:24 +0000
commit10c12d0528cd3b255f9f0e3f5fe1ad96edb99977 (patch)
tree4fbf8fbe537c6476278d4c4dcc7d6b66624084ac /regress
parentd79225514d01fee6189d7c497b6e2c6a6db11eb3 (diff)
Add tests for pf fragment reassembly with all kinds of overlapping.
Some fragments contain invalid data, this must be replaced to reassemble a valid packet.
Diffstat (limited to 'regress')
-rw-r--r--regress/sys/net/pf_fragment/Makefile94
-rw-r--r--regress/sys/net/pf_fragment/frag.py44
-rw-r--r--regress/sys/net/pf_fragment/frag6.py43
-rw-r--r--regress/sys/net/pf_fragment/frag6_cutnew.py52
-rw-r--r--regress/sys/net/pf_fragment/frag6_cutold.py53
-rw-r--r--regress/sys/net/pf_fragment/frag6_dropnew.py57
-rw-r--r--regress/sys/net/pf_fragment/frag6_dropold.py57
-rw-r--r--regress/sys/net/pf_fragment/frag6_ext.py43
-rw-r--r--regress/sys/net/pf_fragment/frag_cutnew.py53
-rw-r--r--regress/sys/net/pf_fragment/frag_cutold.py54
-rw-r--r--regress/sys/net/pf_fragment/frag_dropnew.py58
-rw-r--r--regress/sys/net/pf_fragment/frag_dropold.py58
12 files changed, 664 insertions, 2 deletions
diff --git a/regress/sys/net/pf_fragment/Makefile b/regress/sys/net/pf_fragment/Makefile
index 02ed8e60f19..66fd8e0a098 100644
--- a/regress/sys/net/pf_fragment/Makefile
+++ b/regress/sys/net/pf_fragment/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.1 2011/09/19 22:45:32 bluhm Exp $
+# $OpenBSD: Makefile,v 1.2 2011/09/21 23:48:23 bluhm Exp $
# The following ports must be installed:
#
@@ -162,7 +162,7 @@ run-regress-ping6-mtu: addr.py
.endfor
# Send packet to big to get to destination.
-# Chek that checksum of the quoted original packet in icmp is correct.
+# Check that checksum of the quoted original packet in icmp is correct.
TARGETS += ping-cksum ping6-cksum udp-cksum udp6-cksum
run-regress-ping-cksum: addr.py
@@ -193,6 +193,96 @@ run-regress-udp6-cksum: addr.py
${SUDO} python2.7 udp6_cksum.py ${${ip}6}
.endfor
+# Send handcrafted fragmented packets with overlaps
+TARGETS += frag frag6
+
+run-regress-frag: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping reassembly ${ip}
+ ${SUDO} python2.7 frag.py ${${ip}}
+.endfor
+
+run-regress-frag6: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping6 reassembly ${ip}6
+ ${SUDO} python2.7 frag6.py ${${ip}6}
+.endfor
+
+TARGETS += frag6-ext
+
+run-regress-frag6-ext: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping6 extension header reassembly ${ip}6
+ ${SUDO} python2.7 frag6_ext.py ${${ip}6}
+.endfor
+
+TARGETS += frag-cutnew frag6-cutnew
+
+run-regress-frag-cutnew: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping head overlap reassembly ${ip}
+ ${SUDO} python2.7 frag_cutnew.py ${${ip}}
+.endfor
+
+run-regress-frag6-cutnew: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping6 head overlap reassembly ${ip}6
+ ${SUDO} python2.7 frag6_cutnew.py ${${ip}6}
+.endfor
+
+TARGETS += frag-cutold frag6-cutold
+
+run-regress-frag-cutold: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping tail overlap reassembly ${ip}
+ ${SUDO} python2.7 frag_cutold.py ${${ip}}
+.endfor
+
+run-regress-frag6-cutold: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping6 tail overlap reassembly ${ip}6
+ ${SUDO} python2.7 frag6_cutold.py ${${ip}6}
+.endfor
+
+TARGETS += frag-dropold frag6-dropold
+
+run-regress-frag-dropold: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping total overlapping reassembly ${ip}
+ ${SUDO} python2.7 frag_dropold.py ${${ip}}
+.endfor
+
+run-regress-frag6-dropold: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping6 total overlapping reassembly ${ip}6
+ ${SUDO} python2.7 frag6_dropold.py ${${ip}6}
+.endfor
+
+TARGETS += frag-dropnew frag6-dropnew
+
+run-regress-frag-dropnew: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping total overlaped reassembly ${ip}
+ ${SUDO} python2.7 frag_dropnew.py ${${ip}}
+.endfor
+
+run-regress-frag6-dropnew: addr.py
+ @echo '\n======== $@ ========'
+.for ip in DST_IN RDR_IN
+ @echo Check ping6 total overlaped reassembly ${ip}6
+ ${SUDO} python2.7 frag6_dropnew.py ${${ip}6}
+.endfor
+
REGRESS_TARGETS = ${TARGETS:S/^/run-regress-/}
CLEANFILES += *.pyc *.log
diff --git a/regress/sys/net/pf_fragment/frag.py b/regress/sys/net/pf_fragment/frag.py
new file mode 100644
index 00000000000..de06032f00d
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag.py
@@ -0,0 +1,44 @@
+#!/usr/local/bin/python2.7
+# send 2 non-overlapping ping fragments
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNO"
+packet=IP(src=SRC_OUT, dst=dstaddr)/ICMP(id=pid)/payload
+frag0=str(packet)[20:36]
+frag1=str(packet)[36:44]
+pkt0=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=0, flags='MF')/frag0
+pkt1=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=2)/frag1
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip and src "+dstaddr+" and dst "+SRC_OUT+" and icmp")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.IPv4 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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ load=a.payload.payload.payload.load
+ print "payload=%s" % (load)
+ if load == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)
diff --git a/regress/sys/net/pf_fragment/frag6.py b/regress/sys/net/pf_fragment/frag6.py
new file mode 100644
index 00000000000..c57dc0ae864
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag6.py
@@ -0,0 +1,43 @@
+#!/usr/local/bin/python2.7
+# send 2 non-overlapping ping6 fragments
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNO"
+packet=IPv6(src=SRC_OUT6, dst=dstaddr)/ICMPv6EchoRequest(id=pid, data=payload)
+frag0=IPv6ExtHdrFragment(nh=58, id=pid, m=1)/str(packet)[40:56]
+frag1=IPv6ExtHdrFragment(nh=58, id=pid, offset=2)/str(packet)[56:64]
+pkt0=IPv6(src=SRC_OUT6, dst=dstaddr)/frag0
+pkt1=IPv6(src=SRC_OUT6, dst=dstaddr)/frag1
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip6 and src "+dstaddr+" and dst "+SRC_OUT6+" and icmp6")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ data=a.payload.payload.data
+ print "payload=%s" % (data)
+ if data == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)
diff --git a/regress/sys/net/pf_fragment/frag6_cutnew.py b/regress/sys/net/pf_fragment/frag6_cutnew.py
new file mode 100644
index 00000000000..4413d0668b3
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag6_cutnew.py
@@ -0,0 +1,52 @@
+#!/usr/local/bin/python2.7
+# start of new fragment overlaps old one
+
+# |--------|
+# |>>>>>----|
+
+# If the tail of an older fragment overlaps the beginning of the
+# current fragment, cut the newer fragment.
+# m_adj(frent->fe_m, precut);
+# Newer data wins.
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNO"
+dummy="01234567"
+packet=IPv6(src=SRC_OUT6, dst=dstaddr)/ICMPv6EchoRequest(id=pid, data=payload)
+frag0=IPv6ExtHdrFragment(nh=58, id=pid, m=1)/str(packet)[40:56]
+frag1=IPv6ExtHdrFragment(nh=58, id=pid, offset=1)/(dummy+str(packet)[56:64])
+pkt0=IPv6(src=SRC_OUT6, dst=dstaddr)/frag0
+pkt1=IPv6(src=SRC_OUT6, dst=dstaddr)/frag1
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip6 and src "+dstaddr+" and dst "+SRC_OUT6+" and icmp6")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ data=a.payload.payload.data
+ print "payload=%s" % (data)
+ if data == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)
diff --git a/regress/sys/net/pf_fragment/frag6_cutold.py b/regress/sys/net/pf_fragment/frag6_cutold.py
new file mode 100644
index 00000000000..24cb41722ad
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag6_cutold.py
@@ -0,0 +1,53 @@
+#!/usr/local/bin/python2.7
+# end of new fragment overlaps old one
+
+# |>>>>>----|
+# |--------|
+
+# If the tail of the current framgent overlaps the beginning of an
+# older fragment, cut the older fragment.
+# m_adj(after->fe_m, aftercut);
+# The older data becomes more suspect, and we essentially cause it
+# to be dropped in the end, meaning it will come again.
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNO"
+dummy="01234567"
+packet=IPv6(src=SRC_OUT6, dst=dstaddr)/ICMPv6EchoRequest(id=pid, data=payload)
+frag0=IPv6ExtHdrFragment(nh=58, id=pid, m=1)/str(packet)[40:56]
+frag1=IPv6ExtHdrFragment(nh=58, id=pid, offset=1)/(dummy+str(packet)[56:64])
+pkt0=IPv6(src=SRC_OUT6, dst=dstaddr)/frag0
+pkt1=IPv6(src=SRC_OUT6, dst=dstaddr)/frag1
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip6 and src "+dstaddr+" and dst "+SRC_OUT6+" and icmp6")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ data=a.payload.payload.data
+ print "payload=%s" % (data)
+ if data == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)
diff --git a/regress/sys/net/pf_fragment/frag6_dropnew.py b/regress/sys/net/pf_fragment/frag6_dropnew.py
new file mode 100644
index 00000000000..5275af43c1a
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag6_dropnew.py
@@ -0,0 +1,57 @@
+#!/usr/local/bin/python2.7
+# old fragment completely overlaps new one
+
+# |------------|
+# |XXXX|
+# |----|
+
+# If the current fragment is completely overlapped by existing ones,
+# drop the newer fragment.
+# if (precut >= frent->fe_len)
+# goto bad_fragment;
+# 'Nearer' traffic wins.
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNOQRSTUVWX"
+dummy="01234567"
+packet=IPv6(src=SRC_OUT6, dst=dstaddr)/ICMPv6EchoRequest(id=pid, data=payload)
+frag0=IPv6ExtHdrFragment(nh=58, id=pid, offset=0, m=1)/str(packet)[40:48]
+frag1=IPv6ExtHdrFragment(nh=58, id=pid, offset=2, m=1)/dummy
+frag2=IPv6ExtHdrFragment(nh=58, id=pid, offset=1)/str(packet)[48:72]
+pkt0=IPv6(src=SRC_OUT6, dst=dstaddr)/frag0
+pkt1=IPv6(src=SRC_OUT6, dst=dstaddr)/frag1
+pkt2=IPv6(src=SRC_OUT6, dst=dstaddr)/frag2
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt2)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip6 and src "+dstaddr+" and dst "+SRC_OUT6+" and icmp6")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ data=a.payload.payload.data
+ print "payload=%s" % (data)
+ if data == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)
diff --git a/regress/sys/net/pf_fragment/frag6_dropold.py b/regress/sys/net/pf_fragment/frag6_dropold.py
new file mode 100644
index 00000000000..b3b1573c2e4
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag6_dropold.py
@@ -0,0 +1,57 @@
+#!/usr/local/bin/python2.7
+# new fragment completely overlaps old one
+
+# |----|
+# |XXXX|
+# |------------|
+
+# If an existing fragment is completely overlapped by the current
+# one, drop the older fragment.
+# TAILQ_REMOVE(&frag->fr_queue, after, fr_next);
+# Smaller older fragments might not have been nearer, and might be
+# trying to overwrite a very small part of the full packet.
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNOQRSTUVWX"
+dummy="01234567"
+packet=IPv6(src=SRC_OUT6, dst=dstaddr)/ICMPv6EchoRequest(id=pid, data=payload)
+frag0=IPv6ExtHdrFragment(nh=58, id=pid, offset=0, m=1)/str(packet)[40:48]
+frag1=IPv6ExtHdrFragment(nh=58, id=pid, offset=2, m=1)/dummy
+frag2=IPv6ExtHdrFragment(nh=58, id=pid, offset=1)/str(packet)[48:72]
+pkt0=IPv6(src=SRC_OUT6, dst=dstaddr)/frag0
+pkt1=IPv6(src=SRC_OUT6, dst=dstaddr)/frag1
+pkt2=IPv6(src=SRC_OUT6, dst=dstaddr)/frag2
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt2)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip6 and src "+dstaddr+" and dst "+SRC_OUT6+" and icmp6")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ data=a.payload.payload.data
+ print "payload=%s" % (data)
+ if data == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)
diff --git a/regress/sys/net/pf_fragment/frag6_ext.py b/regress/sys/net/pf_fragment/frag6_ext.py
new file mode 100644
index 00000000000..363320c139b
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag6_ext.py
@@ -0,0 +1,43 @@
+#!/usr/local/bin/python2.7
+# send 2 ping6 fragments with hop-by-hop extension header
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNO"
+packet=IPv6(src=SRC_OUT6, dst=dstaddr)/ICMPv6EchoRequest(id=pid, data=payload)
+frag0=IPv6ExtHdrFragment(nh=58, id=pid, m=1)/str(packet)[40:56]
+frag1=IPv6ExtHdrFragment(nh=58, id=pid, offset=2)/str(packet)[56:64]
+pkt0=IPv6(src=SRC_OUT6, dst=dstaddr)/IPv6ExtHdrHopByHop()/frag0
+pkt1=IPv6(src=SRC_OUT6, dst=dstaddr)/IPv6ExtHdrHopByHop()/frag1
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip6 and src "+dstaddr+" and dst "+SRC_OUT6+" and icmp6")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ data=a.payload.payload.data
+ print "payload=%s" % (data)
+ if data == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)
diff --git a/regress/sys/net/pf_fragment/frag_cutnew.py b/regress/sys/net/pf_fragment/frag_cutnew.py
new file mode 100644
index 00000000000..eb2a86a1e1c
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag_cutnew.py
@@ -0,0 +1,53 @@
+#!/usr/local/bin/python2.7
+# start of new fragment overlaps old one
+
+# |--------|
+# |>>>>>----|
+
+# If the tail of an older fragment overlaps the beginning of the
+# current fragment, cut the newer fragment.
+# m_adj(frent->fe_m, precut);
+# Newer data wins.
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNO"
+dummy="01234567"
+packet=IP(src=SRC_OUT, dst=dstaddr)/ICMP(id=pid)/payload
+frag0=str(packet)[20:36]
+frag1=dummy+str(packet)[36:44]
+pkt0=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=0, flags='MF')/frag0
+pkt1=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=1)/frag1
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip and src "+dstaddr+" and dst "+SRC_OUT+" and icmp")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.IPv4 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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ load=a.payload.payload.payload.load
+ print "payload=%s" % (load)
+ if load == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)
diff --git a/regress/sys/net/pf_fragment/frag_cutold.py b/regress/sys/net/pf_fragment/frag_cutold.py
new file mode 100644
index 00000000000..ea80f20d3aa
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag_cutold.py
@@ -0,0 +1,54 @@
+#!/usr/local/bin/python2.7
+# end of new fragment overlaps old one
+
+# |>>>>>----|
+# |--------|
+
+# If the tail of the current framgent overlaps the beginning of an
+# older fragment, cut the older fragment.
+# m_adj(after->fe_m, aftercut);
+# The older data becomes more suspect, and we essentially cause it
+# to be dropped in the end, meaning it will come again.
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNO"
+dummy="01234567"
+packet=IP(src=SRC_OUT, dst=dstaddr)/ICMP(id=pid)/payload
+frag0=str(packet)[20:36]
+frag1=dummy+str(packet)[36:44]
+pkt0=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=0, flags='MF')/frag0
+pkt1=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=1)/frag1
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip and src "+dstaddr+" and dst "+SRC_OUT+" and icmp")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.IPv4 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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ load=a.payload.payload.payload.load
+ print "payload=%s" % (load)
+ if load == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)
diff --git a/regress/sys/net/pf_fragment/frag_dropnew.py b/regress/sys/net/pf_fragment/frag_dropnew.py
new file mode 100644
index 00000000000..66a49bb50c3
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag_dropnew.py
@@ -0,0 +1,58 @@
+#!/usr/local/bin/python2.7
+# old fragment completely overlaps new one
+
+# |------------|
+# |XXXX|
+# |----|
+
+# If the current fragment is completely overlapped by existing ones,
+# drop the newer fragment.
+# if (precut >= frent->fe_len)
+# goto bad_fragment;
+# 'Nearer' traffic wins.
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNOQRSTUVWX"
+dummy="01234567"
+packet=IP(src=SRC_OUT, dst=dstaddr)/ICMP(id=pid)/payload
+frag0=str(packet)[20:28]
+frag1=dummy
+frag2=str(packet)[28:52]
+pkt0=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=0, flags='MF')/frag0
+pkt1=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=2, flags='MF')/frag1
+pkt2=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=1)/frag2
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt2)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip and src "+dstaddr+" and dst "+SRC_OUT+" and icmp")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.IPv4 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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ load=a.payload.payload.payload.load
+ print "payload=%s" % (load)
+ if load == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)
diff --git a/regress/sys/net/pf_fragment/frag_dropold.py b/regress/sys/net/pf_fragment/frag_dropold.py
new file mode 100644
index 00000000000..24b567afcca
--- /dev/null
+++ b/regress/sys/net/pf_fragment/frag_dropold.py
@@ -0,0 +1,58 @@
+#!/usr/local/bin/python2.7
+# new fragment completely overlaps old one
+
+# |----|
+# |XXXX|
+# |------------|
+
+# If an existing fragment is completely overlapped by the current
+# one, drop the older fragment.
+# TAILQ_REMOVE(&frag->fr_queue, after, fr_next);
+# Smaller older fragments might not have been nearer, and might be
+# trying to overwrite a very small part of the full packet.
+
+import os
+from addr import *
+from scapy.all import *
+
+dstaddr=sys.argv[1]
+pid=os.getpid()
+payload="ABCDEFGHIJKLOMNOQRSTUVWX"
+dummy="01234567"
+packet=IP(src=SRC_OUT, dst=dstaddr)/ICMP(id=pid)/payload
+frag0=str(packet)[20:28]
+frag1=dummy
+frag2=str(packet)[28:52]
+pkt0=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=0, flags='MF')/frag0
+pkt1=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=2, flags='MF')/frag1
+pkt2=IP(src=SRC_OUT, dst=dstaddr, proto=1, id=pid, frag=1)/frag2
+eth=[]
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt0)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt1)
+eth.append(Ether(src=SRC_MAC, dst=PF_MAC)/pkt2)
+
+if os.fork() == 0:
+ time.sleep(1)
+ sendp(eth, iface=SRC_IF)
+ os._exit(0)
+
+ans=sniff(iface=SRC_IF, timeout=3, filter=
+ "ip and src "+dstaddr+" and dst "+SRC_OUT+" and icmp")
+a=ans[0]
+if a and a.type == scapy.layers.dot11.ETHER_TYPES.IPv4 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 != pid:
+ print "WRONG ECHO REPLY ID"
+ exit(2)
+ load=a.payload.payload.payload.load
+ print "payload=%s" % (load)
+ if load == payload:
+ exit(0)
+ print "PAYLOAD!=%s" % (payload)
+ exit(1)
+print "NO ECHO REPLY"
+exit(2)