diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2017-09-07 15:09:02 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2017-09-07 15:09:02 +0000 |
commit | a29225f37e812cfcfa12052b9cf1f987eccb371b (patch) | |
tree | 2d76d119781213bb1c865d993540c7ad0b08dc00 /regress/sys/netinet | |
parent | f6b60c3dfe9f794a3f56d2bd5f2b5f12683c3ec0 (diff) |
Copy IPv6 fragment test cases to IPv4 and adapt to the different
behavior. All tests are run once with pf fragment reassembly and
once with pf disabled and IP input reassembly. Three sub tests are
currently disabled as the IP stack behaves differently than pf.
Diffstat (limited to 'regress/sys/netinet')
21 files changed, 1195 insertions, 0 deletions
diff --git a/regress/sys/netinet/frag/LICENSE b/regress/sys/netinet/frag/LICENSE new file mode 100644 index 00000000000..8132b495a44 --- /dev/null +++ b/regress/sys/netinet/frag/LICENSE @@ -0,0 +1,13 @@ +# Copyright (c) 2012-2017 Alexander Bluhm <bluhm@openbsd.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/regress/sys/netinet/frag/Makefile b/regress/sys/netinet/frag/Makefile new file mode 100644 index 00000000000..ca312d76070 --- /dev/null +++ b/regress/sys/netinet/frag/Makefile @@ -0,0 +1,177 @@ +# $OpenBSD: Makefile,v 1.1.1.1 2017/09/07 15:09:00 bluhm Exp $ + +# The following ports must be installed: +# +# python-2.7 interpreted object-oriented programming language +# py-libdnet python interface to libdnet +# scapy powerful interactive packet manipulation in python + +.if ! (make(clean) || make(cleandir) || make(obj)) +# Check wether all required python packages are installed. If some +# are missing print a warning and skip the tests, but do not fail. +PYTHON_IMPORT !!= python2.7 -c 'from scapy.all import *' 2>&1 || true +.endif + +.if ! empty(PYTHON_IMPORT) +.BEGIN: + @true +regress: + @echo '${PYTHON_IMPORT}' + @echo Install python and the scapy module for additional tests. + @echo SKIPPED +.endif + +# This test needs a manual setup of two machines +# Set up machines: LOCAL REMOTE +# LOCAL is the machine where this makefile is running. +# REMOTE is running OpenBSD with or without pf to test fragment reassemly +# Enable echo udp in inetd.conf on REMOTE to test UDP fragments. +# REMOTE_SSH is used to login and enable or disable pf automatically. + +# Configure addresses on the machines. +# Adapt interface and addresse variables to your local setup. + +LOCAL_IF ?= em1 +LOCAL_MAC ?= 00:1b:21:0e:6e:8e +REMOTE_MAC ?= 00:04:23:b0:68:8e + +LOCAL_ADDR ?= 10.188.81.21 +REMOTE_ADDR ?= 10.188.81.22 + +REMOTE_SSH ?= + +.if empty (LOCAL_IF) || empty (LOCAL_MAC) || empty (REMOTE_MAC) || \ + empty (LOCAL_ADDR) || empty (REMOTE_ADDR) || empty (REMOTE_SSH) +.BEGIN: + @true +regress: + @echo This tests needs a remote machine to operate on. + @echo LOCAL_IF LOCAL_MAC REMOTE_MAC LOCAL_ADDR REMOTE_ADDR REMOTE_SSH + @echo Fill out these variables for additional tests. + @echo SKIPPED +.endif + +.MAIN: all + +.if make (regress) || make (all) +.BEGIN: addr.py + @echo + ${SUDO} true + ssh -t ${REMOTE_SSH} ${SUDO} true + rm -f stamp-stack stamp-pf +.endif + +# Create python include file containing the addresses. +addr.py: Makefile + rm -f $@ $@.tmp + echo 'LOCAL_IF = "${LOCAL_IF}"' >>$@.tmp + echo 'LOCAL_MAC = "${LOCAL_MAC}"' >>$@.tmp + echo 'REMOTE_MAC = "${REMOTE_MAC}"' >>$@.tmp +.for var in LOCAL_ADDR REMOTE_ADDR + echo '${var} = "${${var}}"' >>$@.tmp +.endfor + mv $@.tmp $@ + +# Set variables so that make runs with and without obj directory. +# Only do that if necessary to keep visible output short. +.if ${.CURDIR} == ${.OBJDIR} +PYTHON = python2.7 ./ +.else +PYTHON = PYTHONPATH=${.OBJDIR} python2.7 ${.CURDIR}/ +.endif + +stamp-stack: + rm -f stamp-stack stamp-pf + -ssh ${REMOTE_SSH} ${SUDO} pfctl -d + ssh ${REMOTE_SSH} ${SUDO} pfctl -a regress -Fr + date >$@ + +stamp-pf: addr.py pf.conf + rm -f stamp-stack stamp-pf + cat addr.py ${.CURDIR}/pf.conf | pfctl -n -f - + cat addr.py ${.CURDIR}/pf.conf | \ + ssh ${IPS_SSH} ${SUDO} pfctl -a regress -f - + -ssh ${REMOTE_SSH} ${SUDO} pfctl -e + date >$@ + +REGRESS_TARGETS = +FRAG_SCRIPTS !!= cd ${.CURDIR} && ls -1 frag*.py + +run-regress-stack-frag_mf0long.py: + # the stack allows fragments with data behind a fragment without MF + @echo DISABLED + +run-regress-stack-frag_mf0short.py: + # the stack allows fragments without MF ending before other fragments + @echo DISABLED + +run-regress-stack-frag_mf1end.py: + # the stack allows fragments with MF together with fragments without MF + @echo DISABLED + +.for sp in stack pf + +# Ping all addresses. This ensures that the ip addresses are configured +# and all routing table are set up to allow bidirectional packet flow. +${sp}: run-regress-${sp}-ping +run-regress-${sp}-ping: stamp-${sp} + @echo '\n======== $@ ========' +.for ip in LOCAL_ADDR REMOTE_ADDR + @echo Check ping ${ip}: + ping -n -c 1 ${${ip}} +.endfor + +# Ping all addresses again but with 5000 bytes payload. These large +# packets get fragmented by LOCAL and must be handled by REMOTE. +${sp}: run-regress-${sp}-fragping +run-regress-${sp}-fragping: stamp-${sp} + @echo '\n======== $@ ========' +.for ip in LOCAL_ADDR REMOTE_ADDR + @echo Check ping ${ip}: + ping -n -c 1 -s 5000 ${${ip}} +.endfor + +.for s in ${FRAG_SCRIPTS} +${sp}: run-regress-${sp}-${s} +run-regress-${sp}-${s}: addr.py stamp-${sp} + @echo '\n======== $@ ========' + ${SUDO} ${PYTHON}${s} +.endfor + +REGRESS_TARGETS += run-regress-${sp}-ping run-regress-${sp}-fragping \ + ${FRAG_SCRIPTS:S/^/run-regress-${sp}-/} + +.endfor + +# After running the tests, turn on pf on remote machine. +# This is the expected default configuration. +REGRESS_TARGETS += stamp-pf + +CLEANFILES += addr.py *.pyc *.log stamp-* + +.PHONY: check-setup check-setup-local check-setup-remote + +# Check wether the address, route and remote setup is correct +check-setup: check-setup-local check-setup-remote + +check-setup-local: + @echo '\n======== $@ ========' + ping -n -c 1 ${LOCAL_ADDR} # LOCAL_ADDR + route -n get -inet ${LOCAL_ADDR} |\ + grep -q 'flags: .*LOCAL' # LOCAL_ADDR + ping -n -c 1 ${REMOTE_ADDR} # REMOTE_ADDR + route -n get -inet ${REMOTE_ADDR} |\ + grep -q 'interface: ${LOCAL_IF}$$' # REMOTE_ADDR LOCAL_IF + arp -n ${REMOTE_ADDR} |\ + grep -q ' ${REMOTE_MAC} ' # REMOTE_ADDR REMOTE_MAC + +check-setup-remote: + @echo '\n======== $@ ========' + ssh ${REMOTE_SSH} ping -n -c 1 ${REMOTE_ADDR} # REMOTE_ADDR + ssh ${REMOTE_SSH} route -n get -inet ${REMOTE_ADDR} |\ + grep -q 'flags: .*LOCAL' # REMOTE_ADDR + ssh ${REMOTE_SSH} ping -n -c 1 ${LOCAL_ADDR} # LOCAL_ADDR + ssh ${REMOTE_SSH} arp -n ${LOCAL_ADDR} |\ + grep -q ' ${LOCAL_MAC} ' # LOCAL_ADDR LOCAL_MAC + +.include <bsd.regress.mk> diff --git a/regress/sys/netinet/frag/frag.py b/regress/sys/netinet/frag/frag.py new file mode 100644 index 00000000000..9effca15ccc --- /dev/null +++ b/regress/sys/netinet/frag/frag.py @@ -0,0 +1,51 @@ +#!/usr/local/bin/python2.7 + +print "non-overlapping ping fragments" + +# |--------| +# |----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')/ \ + str(packet)[20:36]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=2)/ \ + str(packet)[36:44]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_mf0long.py b/regress/sys/netinet/frag/frag_mf0long.py new file mode 100644 index 00000000000..6f45a27b8aa --- /dev/null +++ b/regress/sys/netinet/frag/frag_mf0long.py @@ -0,0 +1,55 @@ +#!/usr/local/bin/python2.7 + +print "ping fragment that overlaps longer than the last fragment without MF" + +# |---------| +# |XXXXXXXXX| +# |----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +dummy="0123456701234567" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=1)/ \ + str(packet)[28:44]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=2)/ \ + dummy) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')/ \ + str(packet)[20:28]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_mf0middle.py b/regress/sys/netinet/frag/frag_mf0middle.py new file mode 100644 index 00000000000..012ed81e3d3 --- /dev/null +++ b/regress/sys/netinet/frag/frag_mf0middle.py @@ -0,0 +1,55 @@ +#!/usr/local/bin/python2.7 + +print "ping fragment without MF that overlaps the first fragment" + +# |---------| +# |XXXX| +# |----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +dummy="01234567" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')/ \ + str(packet)[20:36]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=1)/ \ + dummy) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=2)/ \ + str(packet)[36:44]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_mf0short.py b/regress/sys/netinet/frag/frag_mf0short.py new file mode 100644 index 00000000000..5ad6d3e703e --- /dev/null +++ b/regress/sys/netinet/frag/frag_mf0short.py @@ -0,0 +1,55 @@ +#!/usr/local/bin/python2.7 + +print "ping fragment without MF that overlaps the last fragment at beginning" + +# |---------| +# |XXXXXXXXX| +# |---------| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOPQRSTUVWX" +dummy="0123456701234567" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=2)/ \ + str(packet)[36:52]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=1)/ \ + dummy) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')/ \ + str(packet)[20:36]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_mf1end.py b/regress/sys/netinet/frag/frag_mf1end.py new file mode 100644 index 00000000000..446c3f9f03e --- /dev/null +++ b/regress/sys/netinet/frag/frag_mf1end.py @@ -0,0 +1,55 @@ +#!/usr/local/bin/python2.7 + +print "ping fragment with MF that overlaps fragment without MF at the end" + +# |----| +# |XXXXXXXXX| +# |---------| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +dummy="0123456701234567" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=2)/ \ + str(packet)[36:44]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=1, \ + flags='MF')/dummy) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')/ \ + str(packet)[20:36]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_opt.py b/regress/sys/netinet/frag/frag_opt.py new file mode 100644 index 00000000000..824b7481240 --- /dev/null +++ b/regress/sys/netinet/frag/frag_opt.py @@ -0,0 +1,51 @@ +#!/usr/local/bin/python2.7 + +print "ping fragments with IP option" + +# |OOOO--------| +# |----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF', + options=IPOption_NOP())/str(packet)[20:36]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=2)/ \ + str(packet)[36:44]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_overhead.py b/regress/sys/netinet/frag/frag_overhead.py new file mode 100644 index 00000000000..dfcae30a02a --- /dev/null +++ b/regress/sys/netinet/frag/frag_overhead.py @@ -0,0 +1,55 @@ +#!/usr/local/bin/python2.7 + +print "ping fragment that overlaps the second fragment with its head" + +# |----| +# |----| +# |XXXX-----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +dummy="01234567" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF')/str(packet)[20:28]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF', frag=1)/str(packet)[28:36]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + frag=1)/(dummy+str(packet)[36:44])) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_overhead0.py b/regress/sys/netinet/frag/frag_overhead0.py new file mode 100644 index 00000000000..0a1f64721d7 --- /dev/null +++ b/regress/sys/netinet/frag/frag_overhead0.py @@ -0,0 +1,52 @@ +#!/usr/local/bin/python2.7 + +print "ping fragment that overlaps the first fragment with its head" + +# |---------| +# |XXXX-----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +dummy="01234567" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF')/str(packet)[20:36]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + frag=1)/(dummy+str(packet)[36:44])) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_overtail.py b/regress/sys/netinet/frag/frag_overtail.py new file mode 100644 index 00000000000..06175e45f6d --- /dev/null +++ b/regress/sys/netinet/frag/frag_overtail.py @@ -0,0 +1,55 @@ +#!/usr/local/bin/python2.7 + +print "ping fragment that overlaps the second fragment with its tail" + +# |----| +# |XXXX| +# |---------| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +dummy="01234567" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + frag=2)/str(packet)[36:44]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF', frag=1)/dummy) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF')/str(packet)[20:36]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_overtail0.py b/regress/sys/netinet/frag/frag_overtail0.py new file mode 100644 index 00000000000..4c828b43b8a --- /dev/null +++ b/regress/sys/netinet/frag/frag_overtail0.py @@ -0,0 +1,52 @@ +#!/usr/local/bin/python2.7 + +print "ping fragment that overlaps the first fragment with its tail" + +# |XXXX-----| +# |---------| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +dummy="01234567" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + frag=1)/(dummy+str(packet)[36:44])) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF')/str(packet)[20:36]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_padding.py b/regress/sys/netinet/frag/frag_padding.py new file mode 100644 index 00000000000..8fc2af0932c --- /dev/null +++ b/regress/sys/netinet/frag/frag_padding.py @@ -0,0 +1,53 @@ +#!/usr/local/bin/python2.7 + +print "non-overlapping ping fragments with ethernet padding" + +# |--------|XX| +# |----|XX| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +padding="0123" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')/ \ + str(packet)[20:36]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=2)/ \ + str(packet)[36:44]) +eth=[] +for f in frag: + pkt=str(f) + padding + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC, type=0x0800)/pkt) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_permute.py b/regress/sys/netinet/frag/frag_permute.py new file mode 100644 index 00000000000..0596a231e08 --- /dev/null +++ b/regress/sys/netinet/frag/frag_permute.py @@ -0,0 +1,65 @@ +#!/usr/local/bin/python2.7 + +print "send 3 non-overlapping ping fragments in all possible orders" + +# |----| +# |----| +# |----| + +import os +from addr import * +from scapy.all import * + +permute=[] +permute.append([0,1,2]) +permute.append([0,2,1]) +permute.append([1,0,2]) +permute.append([2,0,1]) +permute.append([1,2,0]) +permute.append([2,1,0]) + +pid=os.getpid() +payload="ABCDEFGHIJKLMNOP" +for p in permute: + pid += 1 + eid=pid & 0xffff + packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload + frag=[] + fid=pid & 0xffff + frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, \ + flags='MF')/str(packet)[20:28]) + frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, \ + flags='MF', frag=1)/str(packet)[28:36]) + frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, \ + frag=2)/str(packet)[36:48]) + eth=[] + for i in range(3): + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/frag[p[i]]) + + if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + + ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") + 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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + print "payload=%s" % (data) + if data == payload: + break + print "PAYLOAD!=%s" % (payload) + exit(1) + else: + print "NO ECHO REPLY" + exit(2) diff --git a/regress/sys/netinet/frag/frag_refrag.py b/regress/sys/netinet/frag/frag_refrag.py new file mode 100644 index 00000000000..519cbb7a1c5 --- /dev/null +++ b/regress/sys/netinet/frag/frag_refrag.py @@ -0,0 +1,65 @@ +#!/usr/local/bin/python2.7 + +print "fragments of a large packet that has to be refragmented by reflector" + +# |--------| +# |------------------| +# ... +# |------------------| +# |----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload=100 * "ABCDEFGHIJKLMNOP" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +request_cksum=ICMP(str(packet.payload)).chksum +print "request cksum=%#x" % (request_cksum) +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')/ + str(packet)[20:36]) +offset=2 +chunk=4 +while 40+8*(offset+chunk) < len(payload): + frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF', frag=offset)/ + str(packet)[20+(8*offset):20+8*(offset+chunk)]) + offset+=chunk +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=offset)/ + str(packet)[20+(8*offset):]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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 == 1 and \ + icmptypes[a.payload.payload.type] == 'echo-reply': + id=a.payload.payload.id + print "id=%#x" % (id) + if id != eid: + print "WRONG ECHO REPLY ID" + exit(2) + reply_cksum=a.payload.payload.chksum + print "reply cksum=%#x" % (reply_cksum) + # change request checksum incrementaly and check with reply + diff_cksum=~(~reply_cksum+~(~request_cksum+~0x0800+0x0000)) + if diff_cksum != -1: + print "CHECKSUM ERROR diff cksum=%#x" % (diff_cksum) + exit(1) + exit(0) +print "NO ECHO REPLY" +exit(2) diff --git a/regress/sys/netinet/frag/frag_timeout.py b/regress/sys/netinet/frag/frag_timeout.py new file mode 100644 index 00000000000..1ef9411d720 --- /dev/null +++ b/regress/sys/netinet/frag/frag_timeout.py @@ -0,0 +1,66 @@ +#!/usr/local/bin/python2.7 + +print "6 non-overlapping ping fragments in 75 seconds, timeout is 60" + +# |----| +# |----| +# |----| +# |----| +# |----| <--- timeout +# |----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcd" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF')/str(packet)[20:28]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF', frag=1)/str(packet)[28:36]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF', frag=2)/str(packet)[36:44]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF', frag=3)/str(packet)[44:52]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + flags='MF', frag=4)/str(packet)[52:60]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, + frag=5)/str(packet)[60:68]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + for e in eth: + sendp(e, iface=LOCAL_IF) + time.sleep(15) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=90, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + print "payload=%s" % (data) + if data == payload: + print "ECHO REPLY" + exit(1) + print "PAYLOAD!=%s" % (payload) + exit(1) +print "no echo reply" +exit(0) diff --git a/regress/sys/netinet/frag/frag_udpheader.py b/regress/sys/netinet/frag/frag_udpheader.py new file mode 100644 index 00000000000..8761810d55a --- /dev/null +++ b/regress/sys/netinet/frag/frag_udpheader.py @@ -0,0 +1,54 @@ +#!/usr/local/bin/python2.7 + +print "udp fragments splitted after udp header" + +# |----| +# |--------| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +uport=pid & 0xffff +# inetd ignores UDP packets from privileged port or nfs +if uport < 1024 or uport == 2049: + uport+=1024 +payload="ABCDEFGHIJKLMNOP" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + UDP(sport=uport, dport=7)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=17, id=fid, flags='MF')/ \ + str(packet)[20:28]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=17, id=fid, frag=1)/ \ + str(packet)[28:44]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and udp") +for a in ans: + if a and a.type == ETH_P_IP and \ + a.payload.proto == 17 and \ + a.payload.frag == 0 and a.payload.flags == 0 and \ + a.payload.payload.sport == 7: + port=a.payload.payload.dport + print "port=%d" % (port) + if port != uport: + print "WRONG UDP ECHO REPLY PORT" + exit(2) + data=a.payload.payload.payload.load + print "payload=%s" % (data) + if data == payload: + exit(0) + print "PAYLOAD!=%s" % (payload) + exit(1) +print "NO UDP ECHO REPLY" +exit(2) diff --git a/regress/sys/netinet/frag/frag_udppayload.py b/regress/sys/netinet/frag/frag_udppayload.py new file mode 100644 index 00000000000..f0ca45a60fe --- /dev/null +++ b/regress/sys/netinet/frag/frag_udppayload.py @@ -0,0 +1,54 @@ +#!/usr/local/bin/python2.7 + +print "udp fragments with splitted payload" + +# |--------| +# |----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +uport=pid & 0xffff +# inetd ignores UDP packets from privileged port or nfs +if uport < 1024 or uport == 2049: + uport+=1024 +payload="ABCDEFGHIJKLMNOP" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + UDP(sport=uport, dport=7)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=17, id=fid, flags='MF')/ \ + str(packet)[20:36]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=17, id=fid, frag=2)/ \ + str(packet)[36:44]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and udp") +for a in ans: + if a and a.type == ETH_P_IP and \ + a.payload.proto == 17 and \ + a.payload.frag == 0 and a.payload.flags == 0 and \ + a.payload.payload.sport == 7: + port=a.payload.payload.dport + print "port=%d" % (port) + if port != uport: + print "WRONG UDP ECHO REPLY PORT" + exit(2) + data=a.payload.payload.payload.load + print "payload=%s" % (data) + if data == payload: + exit(0) + print "PAYLOAD!=%s" % (payload) + exit(1) +print "NO UDP ECHO REPLY" +exit(2) diff --git a/regress/sys/netinet/frag/frag_zerofirst.py b/regress/sys/netinet/frag/frag_zerofirst.py new file mode 100644 index 00000000000..287e77f92a4 --- /dev/null +++ b/regress/sys/netinet/frag/frag_zerofirst.py @@ -0,0 +1,53 @@ +#!/usr/local/bin/python2.7 + +print "ping fragment without payload before first fragment" + +# || +# |--------| +# |----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')/ \ + str(packet)[20:36]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=2)/ \ + str(packet)[36:44]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/frag_zerosecond.py b/regress/sys/netinet/frag/frag_zerosecond.py new file mode 100644 index 00000000000..d088a22ed95 --- /dev/null +++ b/regress/sys/netinet/frag/frag_zerosecond.py @@ -0,0 +1,53 @@ +#!/usr/local/bin/python2.7 + +print "ping fragment without payload after first fragment" + +# |--------| +# || +# |----| + +import os +from addr import * +from scapy.all import * + +pid=os.getpid() +eid=pid & 0xffff +payload="ABCDEFGHIJKLMNOP" +packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \ + ICMP(type='echo-request', id=eid)/payload +frag=[] +fid=pid & 0xffff +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')/ \ + str(packet)[20:36]) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, flags='MF')) +frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid, frag=2)/ \ + str(packet)[36:44]) +eth=[] +for f in frag: + eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f) + +if os.fork() == 0: + time.sleep(1) + sendp(eth, iface=LOCAL_IF) + os._exit(0) + +ans=sniff(iface=LOCAL_IF, timeout=3, filter= + "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp") +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: + print "WRONG ECHO REPLY ID" + exit(2) + data=a.payload.payload.payload.load + 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/netinet/frag/pf.conf b/regress/sys/netinet/frag/pf.conf new file mode 100644 index 00000000000..7d101bc927b --- /dev/null +++ b/regress/sys/netinet/frag/pf.conf @@ -0,0 +1,6 @@ +# pf drops IP options by default, test combines frag with IPv4 options +pass inet allow-opts + +# turning on and off pf via ssh connection does not work with states +pass proto tcp from port ssh no state +pass proto tcp to port ssh no state |