1#	$OpenBSD: Makefile,v 1.11 2023/05/24 20:31:49 bluhm Exp $
2
3# Copyright (c) 2017-2020 Alexander Bluhm <bluhm@openbsd.org>
4#
5# Permission to use, copy, modify, and distribute this software for any
6# purpose with or without fee is hereby granted, provided that the above
7# copyright notice and this permission notice appear in all copies.
8#
9# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
17# The following ports must be installed:
18#
19# scapy			powerful interactive packet manipulation in python
20# p5-BSD-Socket-Splice	perl interface to OpenBSD socket splicing
21# p5-Socket6		Perl defines relating to AF_INET6 sockets
22
23.if ! (make(clean) || make(cleandir) || make(obj))
24
25.if ! exists(/usr/local/bin/scapy)
26regress:
27	@echo Install scapy package to run this regress.
28	@echo SKIPPED
29.endif
30
31PERL_REQUIRE !=	perl -Mstrict -Mwarnings -e ' \
32    eval { require BSD::Socket::Splice } or print $@; \
33    eval { require Socket6 } or print $@; \
34'
35.if ! empty (PERL_REQUIRE)
36regress:
37	@echo "${PERL_REQUIRE}"
38	@echo Install these Perl modules for additional tests.
39	@echo SKIPPED
40.endif
41
42PF_STATUS !=	${SUDO} pfctl -si | sed -n 's/^Status: \([^ ]*\) .*/\1/p'
43PF_ANCHOR !=	${SUDO} pfctl -sr | sed -n 's/^anchor "\([^"]*\)" all$$/\1/p'
44.if ! empty(PF_STATUS:MEnabled) && empty(PF_ANCHOR:Mregress)
45regress:
46	@echo pf status: "${PF_STATUS}"
47	@echo pf anchor: "${PF_ANCHOR}"
48	@echo This regress cannot run with pf filtering packets on localhost.
49	@echo Either disable pf or add a line 'anchor "regress"' to pf.conf.
50	@echo There the test will add a stateless rule that passes all packets.
51	@echo SKIPPED
52.endif
53
54.endif
55
56# This test needs a manual setup of two machines
57# Set up machines: LOCAL REMOTE
58# LOCAL is the machine where this makefile is running.
59# REMOTE is running OpenBSD with echo server to test PMTU
60# FAKE is an non existing machine in a non existing network.
61# REMOTE_SSH is the hostname to log in on the REMOTE machine.
62
63# Configure Addresses on the machines.
64# Adapt interface and addresse variables to your local setup.
65#
66LOCAL_IF ?=
67REMOTE_SSH ?=
68
69LOCAL_ADDR ?=
70REMOTE_ADDR ?=
71FAKE_NET ?=
72FAKE_NET_ADDR ?=
73
74.if empty (LOCAL_IF) || empty (REMOTE_SSH) || \
75    empty (LOCAL_ADDR) || \
76    empty (REMOTE_ADDR) || \
77    empty (FAKE_NET) || \
78    empty (FAKE_NET_ADDR)
79.BEGIN:
80	@true
81regress:
82	@echo This tests needs a remote machine to operate on
83	@echo LOCAL_IF REMOTE_SSH LOCAL_ADDR REMOTE_ADDR FAKE_NET FAKE_NET_ADDR
84	@echo are empty.  Fill out these variables for additional tests.
85	@echo SKIPPED
86.endif
87
88.MAIN: all
89
90.if make (regress) || make (all)
91.BEGIN:
92	${SUDO} true
93	ssh -t ${REMOTE_SSH} true
94	@echo
95.endif
96
97# Create python include file containing the addresses.
98addr.py: Makefile
99	rm -f $@ $@.tmp
100	echo 'LOCAL_IF = "${LOCAL_IF}"' >>$@.tmp
101.for var in LOCAL REMOTE FAKE_NET
102	echo '${var}_ADDR = "${${var}_ADDR}"' >>$@.tmp
103.endfor
104	echo 'FAKE_NET = "${FAKE_NET}"' >>$@.tmp
105	mv $@.tmp $@
106
107# load the pf rules into the kernel of the REMOTE and LOCAL machine
108REGRESS_SETUP +=	stamp-pfctl
109stamp-pfctl:
110.if ! empty(PF_ANCHOR:Mregress)
111	echo 'pass on ${LOCAL_IF} no state' | ${SUDO} pfctl -a regress -f -
112.endif
113	@date >$@
114
115SCAPYS !=		cd ${.CURDIR} && ls scapy-*.py
116TARGETS =
117
118# Set variables so that make runs with and without obj directory.
119# Only do that if necessary to keep visible output short.
120.if ${.CURDIR} == ${.OBJDIR}
121PYTHON =	python3 -u
122SCAPYPATH =
123.else
124PYTHON =	PYTHONPATH=${.OBJDIR} python3 -u
125SCAPYPATH =	${.CURDIR}/
126.endif
127
128.for s in ${SCAPYS}
129REGRESS_TARGETS +=	run-$s
130run-$s: $s addr.py
131	time SUDO="${SUDO}" PYTHON="${PYTHON}" perl ${PERLINC} ${PERLPATH}scapy.pl splice ${FAKE_NET_ADDR} ${REMOTE_ADDR} ${REMOTE_SSH} ${SCAPYPATH}$s
132.endfor
133
134.if ! empty(PF_ANCHOR:Mregress)
135REGRESS_CLEANUP +=	cleanup
136cleanup:
137	${SUDO} pfctl -a regress -Fr
138	rm -f stamp-pfctl
139.endif
140
141CLEANFILES +=		addr.py *.pyc *.log stamp-*
142
143.PHONY: check-setup check-setup-local check-setup-remote
144
145# Check wether the address, route and remote setup is correct
146check-setup: check-setup-local check-setup-remote
147
148check-setup-local:
149	@echo '\n======== $@ ========'
150	ping -n -c 1 ${LOCAL_ADDR}  # LOCAL_ADDR
151	route -n get -inet ${LOCAL_ADDR} | grep -q 'flags: .*LOCAL'  # LOCAL_ADDR
152	ping -n -c 1 ${REMOTE_ADDR}  # REMOTE_ADDR
153	route -n get -inet ${REMOTE_ADDR} | fgrep -q 'interface: ${LOCAL_IF}'  # REMOTE_ADDR LOCAL_IF
154	! ping -n -c 1 -w 1 ${FAKE_NET_ADDR}  # FAKE_NET_ADDR
155.for ip in FAKE_NET FAKE_NET_ADDR
156	route -n get -inet ${${ip}} | grep -q 'flags: .*BLACKHOLE'  # ${ip}
157.endfor
158
159check-setup-remote:
160	@echo '\n======== $@ ========'
161	ssh ${REMOTE_SSH} ping -n -c 1 ${REMOTE_ADDR}  # REMOTE_ADDR
162	ssh ${REMOTE_SSH} route -n get -inet ${REMOTE_ADDR} | grep -q 'flags: .*LOCAL'  # REMOTE_ADDR
163	ssh ${REMOTE_SSH} ping -n -c 1 ${LOCAL_ADDR}  # LOCAL_ADDR
164.for ip in FAKE_NET FAKE_NET_ADDR
165	ssh ${REMOTE_SSH} route -n get -inet ${${ip}} | fgrep -q 'gateway: ${LOCAL_ADDR}'  # ${ip} LOCAL_ADDR
166.endfor
167
168.include <bsd.regress.mk>
169