1# $FreeBSD$ 2# 3# SPDX-License-Identifier: BSD-2-Clause-FreeBSD 4# 5# Copyright © 2023 Orange Business Services 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27 28. $(atf_get_srcdir)/utils.subr 29 30sctp_init() 31{ 32 pft_init 33 if ! kldstat -q -m sctp; then 34 atf_skip "This test requires SCTP" 35 fi 36} 37 38atf_test_case "basic_v4" "cleanup" 39basic_v4_head() 40{ 41 atf_set descr 'Basic SCTP connection over IPv4 passthrough' 42 atf_set require.user root 43} 44 45basic_v4_body() 46{ 47 sctp_init 48 49 j="sctp:basic_v4" 50 epair=$(vnet_mkepair) 51 52 vnet_mkjail ${j}a ${epair}a 53 vnet_mkjail ${j}b ${epair}b 54 55 jexec ${j}a ifconfig ${epair}a 192.0.2.1/24 up 56 jexec ${j}b ifconfig ${epair}b 192.0.2.2/24 up 57 # Sanity check 58 atf_check -s exit:0 -o ignore \ 59 jexec ${j}a ping -c 1 192.0.2.2 60 61 jexec ${j}a pfctl -e 62 pft_set_rules ${j}a \ 63 "block" \ 64 "pass in proto sctp to port 1234" 65 66 echo "foo" | jexec ${j}a nc --sctp -N -l 1234 & 67 68 # Wait for the server to start 69 sleep 1 70 71 out=$(jexec ${j}b nc --sctp -N -w 3 192.0.2.1 1234) 72 if [ "$out" != "foo" ]; then 73 atf_fail "SCTP connection failed" 74 fi 75 76 # Now with scrub rules present, so normalization is done 77 pft_set_rules ${j}a \ 78 "scrub on ${j}a" \ 79 "block" \ 80 "pass in proto sctp to port 1234" 81 82 echo "foo" | jexec ${j}a nc --sctp -N -l 1234 & 83 sleep 1 84 85 out=$(jexec ${j}b nc --sctp -N -w 3 192.0.2.1 1234) 86 if [ "$out" != "foo" ]; then 87 atf_fail "SCTP connection failed" 88 fi 89 90 # Now fail with a blocked port 91 echo "foo" | jexec ${j}a nc --sctp -N -l 1235 & 92 sleep 1 93 94 out=$(jexec ${j}b nc --sctp -N -w 3 192.0.2.1 1235) 95 if [ "$out" == "foo" ]; then 96 atf_fail "SCTP port block failed" 97 fi 98 99 # Now fail with a blocked port but passing source port 100 out=$(jexec ${j}b nc --sctp -N -w 3 -p 1234 192.0.2.1 1235) 101 if [ "$out" == "foo" ]; then 102 atf_fail "SCTP port block failed" 103 fi 104} 105 106basic_v4_cleanup() 107{ 108 pft_cleanup 109} 110 111atf_test_case "basic_v6" "cleanup" 112basic_v6_head() 113{ 114 atf_set descr 'Basic SCTP connection over IPv6' 115 atf_set require.user root 116} 117 118basic_v6_body() 119{ 120 sctp_init 121 122 j="sctp:basic_v6" 123 epair=$(vnet_mkepair) 124 125 vnet_mkjail ${j}a ${epair}a 126 vnet_mkjail ${j}b ${epair}b 127 128 jexec ${j}a ifconfig ${epair}a inet6 2001:db8::a/64 up no_dad 129 jexec ${j}b ifconfig ${epair}b inet6 2001:db8::b/64 up no_dad 130 131 # Sanity check 132 atf_check -s exit:0 -o ignore \ 133 jexec ${j}a ping -6 -c 1 2001:db8::b 134 135 jexec ${j}a pfctl -e 136 pft_set_rules ${j}a \ 137 "block proto sctp" \ 138 "pass in proto sctp to port 1234" 139 140 echo "foo" | jexec ${j}a nc -6 --sctp -N -l 1234 & 141 142 # Wait for the server to start 143 sleep 1 144 145 out=$(jexec ${j}b nc --sctp -N -w 3 2001:db8::a 1234) 146 if [ "$out" != "foo" ]; then 147 atf_fail "SCTP connection failed" 148 fi 149 150 # Now with scrub rules present, so normalization is done 151 pft_set_rules ${j}a \ 152 "scrub on ${j}a" \ 153 "block proto sctp" \ 154 "pass in proto sctp to port 1234" 155 156 echo "foo" | jexec ${j}a nc -6 --sctp -N -l 1234 & 157 sleep 1 158 159 out=$(jexec ${j}b nc --sctp -N -w 3 2001:db8::a 1234) 160 if [ "$out" != "foo" ]; then 161 atf_fail "SCTP connection failed" 162 fi 163 164 # Now fail with a blocked port 165 echo "foo" | jexec ${j}a nc -6 --sctp -N -l 1235 & 166 sleep 1 167 168 out=$(jexec ${j}b nc --sctp -N -w 3 2001:db8::a 1235) 169 if [ "$out" == "foo" ]; then 170 atf_fail "SCTP port block failed" 171 fi 172 173 # Now fail with a blocked port but passing source port 174 out=$(jexec ${j}b nc --sctp -N -w 3 -p 1234 2001:db8::a 1235) 175 if [ "$out" == "foo" ]; then 176 atf_fail "SCTP port block failed" 177 fi 178} 179 180basic_v6_cleanup() 181{ 182 pft_cleanup 183} 184 185atf_test_case "abort_v4" "cleanup" 186abort_v4_head() 187{ 188 atf_set descr 'Test sending ABORT messages' 189 atf_set require.user root 190} 191 192abort_v4_body() 193{ 194 sctp_init 195 196 j="sctp:abort_v4" 197 epair=$(vnet_mkepair) 198 199 vnet_mkjail ${j}a ${epair}a 200 vnet_mkjail ${j}b ${epair}b 201 202 jexec ${j}a ifconfig ${epair}a 192.0.2.1/24 up 203 jexec ${j}b ifconfig ${epair}b 192.0.2.2/24 up 204 205 # Sanity check 206 atf_check -s exit:0 -o ignore \ 207 jexec ${j}a ping -c 1 192.0.2.2 208 209 jexec ${j}a pfctl -e 210 pft_set_rules ${j}a \ 211 "block return in proto sctp to port 1234" 212 213 echo "foo" | jexec ${j}a nc --sctp -N -l 1234 & 214 215 # Wait for the server to start 216 sleep 1 217 218 # If we get the abort we'll exit immediately, if we don't timeout will 219 # stop nc. 220 out=$(jexec ${j}b timeout 3 nc --sctp -N 192.0.2.1 1234) 221 if [ $? -eq 124 ]; then 222 atf_fail 'Abort not received' 223 fi 224 if [ "$out" == "foo" ]; then 225 atf_fail "block failed entirely" 226 fi 227 228 # Without 'return' we will time out. 229 pft_set_rules ${j}a \ 230 "block in proto sctp to port 1234" 231 232 out=$(jexec ${j}b timeout 3 nc --sctp -N 192.0.2.1 1234) 233 if [ $? -ne 124 ]; then 234 atf_fail 'Abort sent anyway?' 235 fi 236} 237 238abort_v4_cleanup() 239{ 240 pft_cleanup 241} 242 243atf_test_case "abort_v6" "cleanup" 244abort_v4_head() 245{ 246 atf_set descr 'Test sending ABORT messages over IPv6' 247 atf_set require.user root 248} 249 250abort_v6_body() 251{ 252 sctp_init 253 254 j="sctp:abort_v6" 255 epair=$(vnet_mkepair) 256 257 vnet_mkjail ${j}a ${epair}a 258 vnet_mkjail ${j}b ${epair}b 259 260 jexec ${j}a ifconfig ${epair}a inet6 2001:db8::a/64 no_dad 261 jexec ${j}b ifconfig ${epair}b inet6 2001:db8::b/64 no_dad 262 263 # Sanity check 264 atf_check -s exit:0 -o ignore \ 265 jexec ${j}a ping -6 -c 1 2001:db8::b 266 267 jexec ${j}a pfctl -e 268 pft_set_rules ${j}a \ 269 "block return in proto sctp to port 1234" 270 271 echo "foo" | jexec ${j}a nc -6 --sctp -N -l 1234 & 272 273 # Wait for the server to start 274 sleep 1 275 276 # If we get the abort we'll exit immediately, if we don't timeout will 277 # stop nc. 278 out=$(jexec ${j}b timeout 3 nc --sctp -N 2001:db8::a 1234) 279 if [ $? -eq 124 ]; then 280 atf_fail 'Abort not received' 281 fi 282 if [ "$out" == "foo" ]; then 283 atf_fail "block failed entirely" 284 fi 285 286 # Without 'return' we will time out. 287 pft_set_rules ${j}a \ 288 "block in proto sctp to port 1234" 289 290 out=$(jexec ${j}b timeout 3 nc --sctp -N 2001:db8::a 1234) 291 if [ $? -ne 124 ]; then 292 atf_fail 'Abort sent anyway?' 293 fi 294} 295 296abort_v4_cleanup() 297{ 298 pft_cleanup 299} 300 301atf_init_test_cases() 302{ 303 atf_add_test_case "basic_v4" 304 atf_add_test_case "basic_v6" 305 atf_add_test_case "abort_v4" 306 atf_add_test_case "abort_v6" 307} 308