1*1073f88eSbluhm# $OpenBSD: Makefile,v 1.24 2021/12/12 21:16:53 bluhm Exp $ 2336dfed2Sbluhm 3336dfed2Sbluhm# The following ports must be installed for the regression tests: 4336dfed2Sbluhm# p5-Socket6 Perl defines relating to AF_INET6 sockets 51e607023Sbluhm# 61e607023Sbluhm# Check wether all required perl packages are installed. If some 71e607023Sbluhm# are missing print a warning and skip the tests, but do not fail. 8336dfed2Sbluhm 91e607023SbluhmPERL_REQUIRE != perl -Mstrict -Mwarnings -e ' \ 101e607023Sbluhm eval { require Socket6 } or print $@; \ 111e607023Sbluhm' 121e607023Sbluhm.if ! empty(PERL_REQUIRE) 131e607023Sbluhmregress: 141e607023Sbluhm @echo "${PERL_REQUIRE}" 151e607023Sbluhm @echo install these perl packages for additional tests 1654eefd0cSbluhm @echo SKIPPED 17336dfed2Sbluhm.endif 18336dfed2Sbluhm 19336dfed2Sbluhm# Fill out these variables as you have to test divert with the pf 20336dfed2Sbluhm# kernel running on a remote machine. You have to specify a local 21336dfed2Sbluhm# and remote ip address for the test connections. The fake ip address 22336dfed2Sbluhm# will be routed via the remote address to test divert with non-existing 23336dfed2Sbluhm# addresses. To control the remote machine you need a hostname for 24336dfed2Sbluhm# ssh to log in. All the test files must be in the same directory 25336dfed2Sbluhm# local and remote. 26336dfed2Sbluhm# You must have an anchor "regress" for the divert rules in the pf.conf 27336dfed2Sbluhm# of the remote machine. The kernel of the remote machine gets testet. 2802079822Sbluhm# 2902079822Sbluhm# Run make check-setup to see if you got the setup correct. 30336dfed2Sbluhm 3111f7eadfSbluhmLOCAL_ADDR ?= 3211f7eadfSbluhmREMOTE_ADDR ?= 3311f7eadfSbluhmFAKE_ADDR ?= 3411f7eadfSbluhmLOCAL_ADDR6 ?= 3511f7eadfSbluhmREMOTE_ADDR6 ?= 3611f7eadfSbluhmFAKE_ADDR6 ?= 3711f7eadfSbluhmREMOTE_SSH ?= 38336dfed2Sbluhm 391e607023Sbluhm.if empty (LOCAL_ADDR) || empty (REMOTE_ADDR) || empty (FAKE_ADDR) || \ 401e607023Sbluhm empty (LOCAL_ADDR6) || empty (REMOTE_ADDR6) || empty (FAKE_ADDR6) || \ 411e607023Sbluhm empty (REMOTE_SSH) 421e607023Sbluhmregress: 43aa8f1300Sbluhm @echo This tests needs a remote machine to operate on. 441e607023Sbluhm @echo LOCAL_ADDR REMOTE_ADDR FAKE_ADDR LOCAL_ADDR6 45aa8f1300Sbluhm @echo REMOTE_ADDR6 FAKE_ADDR6 REMOTE_SSH are empty. 46aa8f1300Sbluhm @echo Fill out these variables for additional tests. 4754eefd0cSbluhm @echo SKIPPED 481e607023Sbluhm.endif 491e607023Sbluhm 501e607023Sbluhm# Automatically generate regress targets from test cases in directory. 511e607023Sbluhm 52068b97e5SbluhmPERLS = Client.pm Packet.pm Proc.pm Remote.pm Server.pm \ 53068b97e5Sbluhm funcs.pl remote.pl 541e607023SbluhmARGS != cd ${.CURDIR} && ls args-*.pl 55d76821b9SbluhmTARGETS ?= \ 56d76821b9Sbluhm inet-args-tcp-to inet6-args-tcp-to \ 57d0e91fd6Sbluhm inet-args-tcp-reply inet6-args-tcp-reply \ 58d0e91fd6Sbluhm inet-args-udp-to inet6-args-udp-to \ 59d0e91fd6Sbluhm inet-args-udp-reply inet6-args-udp-reply \ 60c30a42c2Sbluhm inet-args-udp-reply-to inet6-args-udp-reply-to \ 61d0e91fd6Sbluhm inet-args-rip-to inet6-args-rip-to \ 62d0e91fd6Sbluhm inet-args-rip-reply inet6-args-rip-reply \ 63c30a42c2Sbluhm inet-args-rip-reply-to inet6-args-rip-reply-to \ 64d0e91fd6Sbluhm inet-args-icmp-to inet6-args-icmp-to \ 65c30a42c2Sbluhm inet-args-icmp-reply-to inet6-args-icmp-reply-to \ 66c30a42c2Sbluhm inet-args-icmp-reply-reuse inet6-args-icmp-reply-reuse \ 676a1cb87eSbluhm inet-reuse-tcp-to-to inet6-reuse-tcp-to-to \ 686a1cb87eSbluhm inet-reuse-tcp-to-reply inet6-reuse-tcp-to-reply \ 696a1cb87eSbluhm inet-reuse-tcp-reply-to inet6-reuse-tcp-reply-to \ 706a1cb87eSbluhm inet-reuse-tcp-reply-reply inet6-reuse-tcp-reply-reply \ 716a1cb87eSbluhm inet-reuse-udp-to-to inet6-reuse-udp-to-to \ 726a1cb87eSbluhm inet-reuse-udp-to-reply inet6-reuse-udp-to-reply \ 736a1cb87eSbluhm inet-reuse-udp-to-reply-to inet6-reuse-udp-to-reply-to \ 746a1cb87eSbluhm inet-reuse-udp-reply-to inet6-reuse-udp-reply-to \ 756a1cb87eSbluhm inet-reuse-udp-reply-reply inet6-reuse-udp-reply-reply \ 766a1cb87eSbluhm inet-reuse-udp-reply-reply-to inet6-reuse-udp-reply-reply-to \ 776a1cb87eSbluhm inet-reuse-udp-reply-to-to inet6-reuse-udp-reply-to-to \ 786a1cb87eSbluhm inet-reuse-udp-reply-to-reply inet6-reuse-udp-reply-to-reply \ 796a1cb87eSbluhm inet-reuse-udp-reply-to-reply-to inet6-reuse-udp-reply-to-reply-to \ 806a1cb87eSbluhm inet-reuse-rip-to-to inet6-reuse-rip-to-to \ 816a1cb87eSbluhm inet-reuse-rip-to-reply inet6-reuse-rip-to-reply \ 826a1cb87eSbluhm inet-reuse-rip-to-reply-to inet6-reuse-rip-to-reply-to \ 836a1cb87eSbluhm inet-reuse-rip-reply-to inet6-reuse-rip-reply-to \ 846a1cb87eSbluhm inet-reuse-rip-reply-reply inet6-reuse-rip-reply-reply \ 856a1cb87eSbluhm inet-reuse-rip-reply-reply-to inet6-reuse-rip-reply-reply-to \ 866a1cb87eSbluhm inet-reuse-rip-reply-to-to inet6-reuse-rip-reply-to-to \ 876a1cb87eSbluhm inet-reuse-rip-reply-to-reply inet6-reuse-rip-reply-to-reply \ 88068b97e5Sbluhm inet-reuse-rip-reply-to-reply-to inet6-reuse-rip-reply-to-reply-to \ 890c490069Sbluhm inet-args-udp-packet-in inet6-args-udp-packet-in \ 9040df215eSbluhm inet-args-udp-packet-out inet6-args-udp-packet-out 9131432b1dSbluhmREGRESS_TARGETS = ${TARGETS:S/^/run-/} 92d76821b9SbluhmCLEANFILES += *.log *.port *.ktrace ktrace.out stamp-* 931e607023Sbluhm 94336dfed2Sbluhm.MAIN: all 95336dfed2Sbluhm 961e607023Sbluhm.if ! empty (REMOTE_SSH) 97336dfed2Sbluhm.if make (regress) || make (all) 98336dfed2Sbluhm.BEGIN: 99336dfed2Sbluhm @echo 100336dfed2Sbluhm ${SUDO} true 1011e607023Sbluhm ssh -t ${REMOTE_SSH} ${SUDO} true 1021e607023Sbluhm.if ! empty (FAKE_ADDR) && ! empty (REMOTE_ADDR) 103336dfed2Sbluhm -${SUDO} route -n delete -inet -host ${FAKE_ADDR} 2>/dev/null 104336dfed2Sbluhm ${SUDO} route -n add -inet -host ${FAKE_ADDR} ${REMOTE_ADDR} 1051e607023Sbluhm.endif 1061e607023Sbluhm.if ! empty (FAKE_ADDR6) && ! empty (REMOTE_ADDR6) 107336dfed2Sbluhm -${SUDO} route -n delete -inet6 -host ${FAKE_ADDR6} 2>/dev/null 108336dfed2Sbluhm ${SUDO} route -n add -inet6 -host ${FAKE_ADDR6} ${REMOTE_ADDR6} 109336dfed2Sbluhm.endif 1101e607023Sbluhm.endif 1111e607023Sbluhm.endif 112336dfed2Sbluhm 113336dfed2Sbluhm# Set variables so that make runs with and without obj directory. 114336dfed2Sbluhm# Only do that if necessary to keep visible output short. 115336dfed2Sbluhm 116336dfed2Sbluhm.if ${.CURDIR} == ${.OBJDIR} 117336dfed2SbluhmPERLINC = -I. 118336dfed2SbluhmPERLPATH = 119336dfed2Sbluhm.else 120336dfed2SbluhmPERLINC = -I${.CURDIR} 121336dfed2SbluhmPERLPATH = ${.CURDIR}/ 122336dfed2Sbluhm.endif 123336dfed2Sbluhm 124336dfed2Sbluhm# The arg tests take a perl hash with arguments controlling the test 125336dfed2Sbluhm# parameters. The remote.pl test has local client or server and the 126336dfed2Sbluhm# diverted process is running on the remote machine reachable with 127336dfed2Sbluhm# ssh. 128336dfed2Sbluhm 129d0e91fd6Sbluhm.for inet addr in inet ADDR inet6 ADDR6 130d0e91fd6Sbluhm 13131432b1dSbluhmrun-${inet}-reuse-rip-to-reply-to: 1326a1cb87eSbluhm @echo 'rip to before reply is broken, it does not remove the state.' 1336a1cb87eSbluhm @echo DISABLED 1346a1cb87eSbluhm 135336dfed2Sbluhm.for a in ${ARGS} 13631432b1dSbluhmrun-${inet}-${a:R}: ${a} 137068b97e5Sbluhm.if ${@:M*-packet-*} 138d76821b9Sbluhm time ${SUDO} SUDO=${SUDO} KTRACE=${KTRACE} \ 139d76821b9Sbluhm perl ${PERLINC} ${PERLPATH}remote.pl -f ${inet} \ 140d76821b9Sbluhm ${LOCAL_${addr}} ${REMOTE_${addr}} ${REMOTE_SSH} \ 141d76821b9Sbluhm ${PERLPATH}${a} 142068b97e5Sbluhm.else 143d76821b9Sbluhm time ${SUDO} SUDO=${SUDO} KTRACE=${KTRACE} \ 144d76821b9Sbluhm perl ${PERLINC} ${PERLPATH}remote.pl -f ${inet} \ 145d76821b9Sbluhm ${LOCAL_${addr}} ${FAKE_${addr}} ${REMOTE_SSH} \ 146d76821b9Sbluhm ${PERLPATH}${a} 147068b97e5Sbluhm.endif 148d0e91fd6Sbluhm.endfor 149d0e91fd6Sbluhm 1502316dd1bSbluhmSTATE_EXIST_tcp_to = ! 1512316dd1bSbluhmSTATE_EXIST_udp_to = 1522316dd1bSbluhmSTATE_EXIST_rip_to = 1532316dd1bSbluhmSTATE_EXIST_tcp_reply = ! 1542316dd1bSbluhmSTATE_EXIST_udp_reply = ! 1552316dd1bSbluhmSTATE_EXIST_rip_reply = ! 1562316dd1bSbluhmSTATE_EXIST_tcp_reply-to = ! 1572316dd1bSbluhmSTATE_EXIST_udp_reply-to = ! 1582316dd1bSbluhmSTATE_EXIST_rip_reply-to = ! 1592316dd1bSbluhm 160d0e91fd6Sbluhm.for proto in tcp udp rip 1616a1cb87eSbluhm 1626a1cb87eSbluhm.for first second in to to to reply to reply-to reply to reply reply reply reply-to reply-to to reply-to reply reply-to reply-to 1636a1cb87eSbluhm 16431432b1dSbluhmrun-${inet}-reuse-${proto}-${first}-${second}: 1652316dd1bSbluhm # create state with ${first} divert rule 166d76821b9Sbluhm time ${SUDO} SUDO=${SUDO} KTRACE=${KTRACE} \ 167d76821b9Sbluhm perl ${PERLINC} ${PERLPATH}remote.pl -f ${inet} \ 168d76821b9Sbluhm ${LOCAL_${addr}} ${FAKE_${addr}} ${REMOTE_SSH} \ 169d76821b9Sbluhm ${PERLPATH}args-${proto}-${first}.pl 170d0e91fd6Sbluhm sed -n '/^connect peer:/s/.* //p' client.log >client.port 171d0e91fd6Sbluhm sed -n '/^connect sock:/s/.* //p' client.log >server.port 172d0e91fd6Sbluhm.if "tcp" == ${proto} 1732316dd1bSbluhm # drop client tcp socket still in time wait to allow reuse 1742316dd1bSbluhm.if "reply" == ${first} || "reply-to" == ${first} 175d76821b9Sbluhm ${SUDO} tcpdrop \ 176d76821b9Sbluhm ${LOCAL_${addr}} `cat client.port` \ 177d76821b9Sbluhm ${FAKE_${addr}} `cat server.port` 1780c2ea69fSbluhm # to avoid SYN retransmit, kill local tcp state that will be reused 1790c2ea69fSbluhm.if "inet" == ${inet} 1800c2ea69fSbluhm ${SUDO} pfctl -k key -k '${proto} ${LOCAL_${addr}}:'`cat client.port`' <- ${FAKE_${addr}}:'`cat server.port`'' 1810c2ea69fSbluhm.elif "inet6" == ${inet} 1820c2ea69fSbluhm ${SUDO} pfctl -k key -k '${proto} ${LOCAL_${addr}}['`cat client.port`'] <- ${FAKE_${addr}}['`cat server.port`']' 1830c2ea69fSbluhm.endif 1842316dd1bSbluhm.else # "to" == ${first} 1850c2ea69fSbluhm # to avoid SYN retransmit, kill local tcp state that will be reused 1860c2ea69fSbluhm.if "inet" == ${inet} 1870c2ea69fSbluhm ${SUDO} pfctl -k key -k '${proto} ${LOCAL_${addr}}:'`cat server.port`' -> ${FAKE_${addr}}:'`cat client.port`'' 1880c2ea69fSbluhm.elif "inet6" == ${inet} 1890c2ea69fSbluhm ${SUDO} pfctl -k key -k '${proto} ${LOCAL_${addr}}['`cat server.port`'] -> ${FAKE_${addr}}['`cat client.port`']' 1900c2ea69fSbluhm.endif 1912316dd1bSbluhm # tcp socket is in time wait so state must still exist 1922316dd1bSbluhm ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | \ 1930c2ea69fSbluhm egrep 'all ${proto} ${FAKE_${addr}}:?\[?'`cat client.port`'\]? .. ${LOCAL_${addr}}:?\[?'`cat server.port`'\]? ' 194d76821b9Sbluhm ssh ${REMOTE_SSH} ${SUDO} tcpdrop \ 195d76821b9Sbluhm ${FAKE_${addr}} `cat client.port` \ 196d76821b9Sbluhm ${LOCAL_${addr}} `cat server.port` 1972316dd1bSbluhm # divert-to state disappeared when the tcp socket was dropped 1982316dd1bSbluhm ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | ! \ 1990c2ea69fSbluhm egrep 'all ${proto} ${FAKE_${addr}}:?\[?'`cat client.port`'\]? .. ${LOCAL_${addr}}:?\[?'`cat server.port`'\]? ' 2006a1cb87eSbluhm.endif 2016a1cb87eSbluhm.endif 2022316dd1bSbluhm.if "to" == ${first} 2032316dd1bSbluhm.if "tcp" == ${proto} 2042316dd1bSbluhm # divert-to state has disappeared as tcp socket is always connected 2052316dd1bSbluhm.else 2062316dd1bSbluhm # divert-to state still exists as the socket is unconnected 2072316dd1bSbluhm.endif 2082316dd1bSbluhm.else 2092316dd1bSbluhm # divert-reply state has disappeared when the connected socket closed 2102316dd1bSbluhm.endif 2112316dd1bSbluhm ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | ${STATE_EXIST_${proto}_${first}} \ 2122316dd1bSbluhm egrep ' (tcp|udp|254) ${FAKE_${addr}}[][0-9:]* .. ${LOCAL_${addr}}[][0-9:]* ' 2132316dd1bSbluhm # create state again with ${second} divert rule 214d76821b9Sbluhm time ${SUDO} SUDO=${SUDO} KTRACE=${KTRACE} \ 215d76821b9Sbluhm perl ${PERLINC} ${PERLPATH}remote.pl ${inet} \ 216d76821b9Sbluhm ${LOCAL_${addr}} ${FAKE_${addr}} ${REMOTE_SSH} \ 217d76821b9Sbluhm `cat client.port` `cat server.port` \ 218d76821b9Sbluhm ${PERLPATH}args-${proto}-${second}.pl 2193c0bd7e8Sbluhm.if "tcp" == ${proto} 2202316dd1bSbluhm.if "reply" == ${second} || "reply-to" == ${second} 2212316dd1bSbluhm # drop client tcp socket still in time wait to clean up 222d76821b9Sbluhm ${SUDO} tcpdrop \ 223d76821b9Sbluhm ${LOCAL_${addr}} `cat server.port` \ 224d76821b9Sbluhm ${FAKE_${addr}} `cat client.port` 2252316dd1bSbluhm.else # "to" == ${second} 2262316dd1bSbluhm # dropping the server tcp socket in time wait must remove the state 2276a1cb87eSbluhm ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | \ 2280c2ea69fSbluhm egrep 'all ${proto} ${FAKE_${addr}}:?\[?'`cat server.port`'\]? .. ${LOCAL_${addr}}:?\[?'`cat client.port`'\]? ' 229d76821b9Sbluhm ssh ${REMOTE_SSH} ${SUDO} tcpdrop \ 230d76821b9Sbluhm ${FAKE_${addr}} `cat server.port` \ 231d76821b9Sbluhm ${LOCAL_${addr}} `cat client.port` 2322316dd1bSbluhm ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | ! \ 2330c2ea69fSbluhm egrep 'all ${proto} ${FAKE_${addr}}:?\[?'`cat server.port`'\]? .. ${LOCAL_${addr}}:?\[?'`cat client.port`'\]? ' 234cee6974dSbluhm.endif 235cee6974dSbluhm.endif 2362316dd1bSbluhm # states must disappear after connected socket has been closed 2372316dd1bSbluhm ssh ${REMOTE_SSH} ${SUDO} pfctl -ss | ${STATE_EXIST_${proto}_${second}} \ 2382316dd1bSbluhm egrep ' (tcp|udp|254) ${FAKE_${addr}}[][0-9:]* .. ${LOCAL_${addr}}[][0-9:]* ' 239d0e91fd6Sbluhm 240336dfed2Sbluhm.endfor 2416a1cb87eSbluhm.endfor 2426a1cb87eSbluhm.endfor 243336dfed2Sbluhm 24479a2adffSbluhm.PHONY: syntax check-setup 245336dfed2Sbluhm 2463c0bd7e8Sbluhm# make perl syntax check for all args files 247336dfed2Sbluhmsyntax: stamp-syntax 248336dfed2Sbluhm 249068b97e5Sbluhmstamp-syntax: ${PERLS} ${ARGS} 250068b97e5Sbluhm.for p in ${PERLS} 251068b97e5Sbluhm @perl -c ${PERLINC} ${PERLPATH}$p 252068b97e5Sbluhm.endfor 253336dfed2Sbluhm.for a in ${ARGS} 254336dfed2Sbluhm @perl -c ${PERLPATH}$a 255336dfed2Sbluhm.endfor 256336dfed2Sbluhm @date >$@ 257336dfed2Sbluhm 25879a2adffSbluhm# Check wether the address, route and remote setup is correct 25979a2adffSbluhmcheck-setup: 26002079822Sbluhm @echo '\n======== $@ ========' 26179a2adffSbluhm ping -n -c 1 ${LOCAL_ADDR} 26279a2adffSbluhm ping -n -c 1 ${REMOTE_ADDR} 26379a2adffSbluhm ping6 -n -c 1 ${LOCAL_ADDR6} 26479a2adffSbluhm ping6 -n -c 1 ${REMOTE_ADDR6} 2653c0bd7e8Sbluhm route -n get -inet ${FAKE_ADDR} | grep 'if address: ${LOCAL_ADDR}$$' 2663c0bd7e8Sbluhm route -n get -inet ${FAKE_ADDR} | grep 'gateway: ${REMOTE_ADDR}$$' 2673c0bd7e8Sbluhm route -n get -inet6 ${FAKE_ADDR6} | grep 'if address: ${LOCAL_ADDR6}$$' 2683c0bd7e8Sbluhm route -n get -inet6 ${FAKE_ADDR6} | grep 'gateway: ${REMOTE_ADDR6}$$' 26979a2adffSbluhm ssh ${REMOTE_SSH} ${SUDO} pfctl -sr | grep '^anchor "regress" all$$' 27079a2adffSbluhm ssh ${REMOTE_SSH} ${SUDO} pfctl -si | grep '^Status: Enabled ' 271*1073f88eSbluhm ssh ${REMOTE_SSH} perl -MSocket6 -e 1 27279a2adffSbluhm 273336dfed2Sbluhm.include <bsd.regress.mk> 274