1#! /usr/libexec/atf-sh 2#- 3# SPDX-License-Identifier: BSD-2-Clause 4# 5# Copyright (c) 2026 Boris Lytochkin 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# 29 30common_dir="$(atf_get_srcdir)/../common" 31. ${common_dir}/utils.subr 32 33NC="nc -w 1 -dnN" 34 35setup_network_v4() 36{ 37 epair="$1" 38 39 atf_check ifconfig ${epair}a 192.0.2.0/31 up 40 41 vnet_mkjail alcatraz ${epair}b 42 43 atf_check jexec alcatraz ifconfig ${epair}b 192.0.2.1/31 up 44 45 atf_check jexec alcatraz inetd -p $(pwd)/inetd.pid $(atf_get_srcdir)/lookup_inetd.conf 46 47 # Sanity checks 48 atf_check -o ignore ping -i .1 -c 3 -s 1200 192.0.2.1 49 atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82 50 51} 52 53atf_test_case "ip4" "cleanup" 54ip4_head() 55{ 56 atf_set descr 'IPv4 lookup test' 57 atf_set require.user root 58 atf_set require.progs scapy 59} 60 61ip4_body() 62{ 63 firewall_init "ipfw" 64 65 epair=$(vnet_mkepair) 66 67 setup_network_v4 ${epair} 68 69 # Source address match 70 firewall_config "alcatraz" ipfw ipfw \ 71 "ipfw -q table 1 create type addr" \ 72 "ipfw -q table 1 add 192.0.2.0/32" \ 73 "ipfw -q add 100 unreach port tcp from any to any lookup src-ip 1 in" 74 atf_check -s exit:1 ${NC} 192.0.2.1 82 75 76 # Destination address match 77 firewall_config "alcatraz" ipfw ipfw \ 78 "ipfw -q table 1 create type addr" \ 79 "ipfw -q table 1 add 192.0.2.1/32" \ 80 "ipfw -q add 100 unreach port tcp from any to any lookup dst-ip 1 in" 81 atf_check -s exit:1 ${NC} 192.0.2.1 82 82 83 # Masked part 84 85 # Masked source address match 86 firewall_config "alcatraz" ipfw ipfw \ 87 "ipfw -q table 1 create type addr" \ 88 "ipfw -q table 1 add 192.0.0.0/32" \ 89 "ipfw -q add 100 allow tcp from any to any lookup src-ip4:255.255.253.255 1 in" \ 90 "ipfw -q add 200 unreach port ip from any to any in" 91 atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82 92 93 # Masked destination address match 94 firewall_config "alcatraz" ipfw ipfw \ 95 "ipfw -q table 1 create type addr" \ 96 "ipfw -q table 1 add 192.0.0.1/32" \ 97 "ipfw -q add 100 allow tcp from any to any lookup dst-ip4:255.255.253.255 1 in" \ 98 "ipfw -q add 200 unreach port ip from any to any in" 99 atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82 100 101 # Masked source address !match 102 firewall_config "alcatraz" ipfw ipfw \ 103 "ipfw -q table 1 create type addr" \ 104 "ipfw -q table 1 add 192.0.0.0/32" \ 105 "ipfw -q add 100 allow tcp from any to any lookup src-ip4:128.255.253.255 1 in" \ 106 "ipfw -q add 200 unreach port ip from any to any in" 107 atf_check -s exit:1 ${NC} 192.0.2.1 82 108 109 # Masked destination address !match 110 firewall_config "alcatraz" ipfw ipfw \ 111 "ipfw -q table 1 create type addr" \ 112 "ipfw -q table 1 add 192.0.2.1/32" \ 113 "ipfw -q add 100 allow tcp from any to any lookup dst-ip4:128.255.255.255 1 in" \ 114 "ipfw -q add 200 unreach port ip from any to any in" 115 atf_check -s exit:1 ${NC} 192.0.2.1 82 116 117} 118 119 120setup_network_v6() 121{ 122 epair="$1" 123 124 atf_check ifconfig ${epair}a inet6 2001:db8:42::1/64 up no_dad -ifdisabled 125 126 vnet_mkjail alcatraz ${epair}b 127 128 atf_check jexec alcatraz ifconfig ${epair}b inet6 2001:db8:42::2/64 up no_dad 129 130 atf_check jexec alcatraz inetd -p $(pwd)/inetd.pid $(atf_get_srcdir)/lookup_inetd.conf 131 132 # Sanity checks 133 atf_check -o ignore ping6 -i .1 -c 3 -s 1200 2001:db8:42::2 134 atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82 135 136} 137 138atf_test_case "ip6" "cleanup" 139ip6_head() 140{ 141 atf_set descr 'IPv6 lookup test' 142 atf_set require.user root 143 atf_set require.progs scapy 144} 145 146ip6_body() 147{ 148 firewall_init "ipfw" 149 150 epair=$(vnet_mkepair) 151 152 setup_network_v6 ${epair} 153 154 # Source address match 155 firewall_config "alcatraz" ipfw ipfw \ 156 "ipfw -q table 1 create type addr" \ 157 "ipfw -q table 1 add 2001:db8:42::1/128" \ 158 "ipfw -q add 100 unreach port tcp from any to any lookup src-ip 1 in" 159 atf_check -s exit:1 ${NC} 2001:db8:42::2 82 160 161 # Destination address match 162 firewall_config "alcatraz" ipfw ipfw \ 163 "ipfw -q table 1 create type addr" \ 164 "ipfw -q table 1 add 2001:db8:42::2/128" \ 165 "ipfw -q add 100 unreach port tcp from any to any lookup dst-ip 1 in" 166 atf_check -s exit:1 ${NC} 2001:db8:42::2 82 167 168 # Source address match 169 firewall_config "alcatraz" ipfw ipfw \ 170 "ipfw -q table 1 create type addr" \ 171 "ipfw -q table 1 add 2000::/64" \ 172 "ipfw -q add 100 unreach port tcp from any to any lookup src-ip 1 in" 173 atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82 174 175 # Masked part 176 177 # Masked source address match 178 firewall_config "alcatraz" ipfw ipfw \ 179 "ipfw -q table 1 create type addr" \ 180 "ipfw -q table 1 add 2000:db8:42::1/128" \ 181 "ipfw -q add 100 allow tcp from any to any lookup src-ip6:fff0:ffff:ffff:ffff:ffff:ffff:ffff:ffff 1 in" \ 182 "ipfw -q add 200 unreach port tcp from any to any in" 183 atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82 184 185 # Destination address match 186 firewall_config "alcatraz" ipfw ipfw \ 187 "ipfw -q table 1 create type addr" \ 188 "ipfw -q table 1 add 2001:0:42::2/128" \ 189 "ipfw -q add 100 allow tcp from any to any lookup dst-ip6:ffff:0:ffff:ffff:ffff:ffff:ffff:ffff 1 in" \ 190 "ipfw -q add 200 count tcp from any to any in" 191 atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82 192 193 # Masked source address !match 194 firewall_config "alcatraz" ipfw ipfw \ 195 "ipfw -q table 1 create type addr" \ 196 "ipfw -q table 1 add 2001:db8:42::1/128" \ 197 "ipfw -q add 100 allow tcp from any to any lookup src-ip6:fff0:ffff:ffff:ffff:ffff:ffff:ffff:ffff 1 in" \ 198 "ipfw -q add 200 unreach port tcp from any to any in" 199 atf_check -s exit:1 ${NC} 2001:db8:42::2 82 200 201 # Masked destination address !match 202 firewall_config "alcatraz" ipfw ipfw \ 203 "ipfw -q table 1 create type addr" \ 204 "ipfw -q table 1 add 2000:0:42::2/128" \ 205 "ipfw -q add 100 allow tcp from any to any lookup dst-ip6:ffff:0:ffff:ffff:ffff:ffff:ffff:ffff 1 in" \ 206 "ipfw -q add 200 unreach port tcp from any to any in" 207 atf_check -s exit:1 ${NC} 2001:db8:42::2 82 208 209} 210 211atf_test_case "rulenum" "cleanup" 212rulenum_head() 213{ 214 atf_set descr 'Rule number lookup test' 215 atf_set require.user root 216} 217 218rulenum_body() 219{ 220 firewall_init "ipfw" 221 222 epair=$(vnet_mkepair) 223 224 setup_network_v6 ${epair} 225 226 firewall_config "alcatraz" ipfw ipfw \ 227 "ipfw -q table 1 create type number" \ 228 "ipfw -q table 1 add 100" \ 229 "ipfw -q add 100 unreach port tcp from any to any lookup rulenum 1 in" 230 atf_check -s exit:1 ${NC} 2001:db8:42::2 82 231 232 firewall_config "alcatraz" ipfw ipfw \ 233 "ipfw -q table 1 create type number" \ 234 "ipfw -q table 1 add 101" \ 235 "ipfw -q add 100 unreach port tcp from any to any lookup rulenum 1 in" 236 atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82 237 238 # Masked part 239 240 firewall_config "alcatraz" ipfw ipfw \ 241 "ipfw -q table 1 create type number" \ 242 "ipfw -q table 1 add 96" \ 243 "ipfw -q add 100 unreach port tcp from any to any lookup rulenum:0x60 1 in" 244 atf_check -s exit:1 ${NC} 2001:db8:42::2 82 245 246 firewall_config "alcatraz" ipfw ipfw \ 247 "ipfw -q table 1 create type number" \ 248 "ipfw -q table 1 add 101" \ 249 "ipfw -q add 100 unreach port tcp from any to any lookup rulenum:32 1 in" 250 atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82 251 252} 253 254atf_test_case "port" "cleanup" 255port_head() 256{ 257 atf_set descr 'Lookup src-/dst-port works' 258 atf_set require.user root 259} 260 261port_body() 262{ 263 firewall_init "ipfw" 264 265 epair=$(vnet_mkepair) 266 267 setup_network_v4 ${epair} 268 269 firewall_config "alcatraz" ipfw ipfw \ 270 "ipfw -q table 1 create type number" \ 271 "ipfw -q table 1 add 82" \ 272 "ipfw add 10 allow tcp from any to any lookup dst-port 1 in" \ 273 "ipfw add 20 unreach port tcp from any to any dst-port 82" 274 atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82 275 276 firewall_config "alcatraz" ipfw ipfw \ 277 "ipfw -q table 1 create type number" \ 278 "ipfw -q table 1 add 80" \ 279 "ipfw add 10 allow tcp from any to any lookup dst-port 1 in" \ 280 "ipfw add 20 unreach port tcp from any to any dst-port 82" 281 atf_check -s exit:1 ${NC} 192.0.2.1 82 282 283 firewall_config "alcatraz" ipfw ipfw \ 284 "ipfw -q table 1 create type number" \ 285 "ipfw -q table 1 add 82" \ 286 "ipfw add 10 allow tcp from any to any lookup src-port 1 out" \ 287 "ipfw add 20 unreach port tcp from any to any src-port 82 out" 288 atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82 289 290 firewall_config "alcatraz" ipfw ipfw \ 291 "ipfw -q table 1 create type number" \ 292 "ipfw -q table 1 add 80" \ 293 "ipfw add 10 allow tcp from any to any lookup src-port 1 in" \ 294 "ipfw add 20 unreach port tcp from any to any src-port 22222 in" 295 atf_check -s exit:1 ${NC} -p 22222 192.0.2.1 82 296 297 # Masked part 298 299 firewall_config "alcatraz" ipfw ipfw \ 300 "ipfw -q table 1 create type number" \ 301 "ipfw -q table 1 add 18" \ 302 "ipfw add 10 allow tcp from any to any lookup dst-port:0x1F 1 in" \ 303 "ipfw add 20 unreach port tcp from any to any dst-port 82" 304 atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82 305 306 firewall_config "alcatraz" ipfw ipfw \ 307 "ipfw -q table 1 create type number" \ 308 "ipfw -q table 1 add 18" \ 309 "ipfw add 10 allow tcp from any to any lookup dst-port:255 1 in" \ 310 "ipfw add 20 unreach port tcp from any to any dst-port 82" 311 atf_check -s exit:1 ${NC} 192.0.2.1 82 312} 313 314atf_test_case "dscp_v6" "cleanup" 315dscp_v6_head() 316{ 317 atf_set descr 'DSCP for IPv6 lookup test' 318 atf_set require.user root 319} 320 321dscp_v6_body() 322{ 323 firewall_init "ipfw" 324 325 epair=$(vnet_mkepair) 326 327 setup_network_v6 ${epair} 328 329 firewall_config "alcatraz" ipfw ipfw \ 330 "ipfw -q table 1 create type number" \ 331 "ipfw -q table 1 add 12" \ 332 "ipfw -q add 50 setdscp 12 tcp from any to any" \ 333 "ipfw -q add 100 unreach port tcp from any to any lookup dscp 1 in" 334 atf_check -s exit:1 ${NC} 2001:db8:42::2 82 335 336 firewall_config "alcatraz" ipfw ipfw \ 337 "ipfw -q table 1 create type number" \ 338 "ipfw -q table 1 add 101" \ 339 "ipfw -q add 50 setdscp 12 tcp from any to any" \ 340 "ipfw -q add 100 unreach port tcp from any to any lookup dscp 1 in" 341 atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82 342 343 # Masked part 344 345 firewall_config "alcatraz" ipfw ipfw \ 346 "ipfw -q table 1 create type number" \ 347 "ipfw -q table 1 add 12" \ 348 "ipfw -q add 50 setdscp 13 tcp from any to any" \ 349 "ipfw -q add 100 unreach port tcp from any to any lookup dscp:0xFE 1 in" 350 atf_check -s exit:1 ${NC} 2001:db8:42::2 82 351 352 firewall_config "alcatraz" ipfw ipfw \ 353 "ipfw -q table 1 create type number" \ 354 "ipfw -q table 1 add 13" \ 355 "ipfw -q add 50 setdscp 13 tcp from any to any" \ 356 "ipfw -q add 100 unreach port tcp from any to any lookup dscp:1 1 in" 357 atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82 358 359} 360 361atf_test_case "dscp_v4" "cleanup" 362dscp_v4_head() 363{ 364 atf_set descr 'Lookup DSCP for IPv4 test' 365 atf_set require.user root 366} 367 368dscp_v4_body() 369{ 370 firewall_init "ipfw" 371 372 epair=$(vnet_mkepair) 373 374 setup_network_v4 ${epair} 375 376 firewall_config "alcatraz" ipfw ipfw \ 377 "ipfw -q table 1 create type number" \ 378 "ipfw -q table 1 add 12" \ 379 "ipfw -q add 50 setdscp 12 tcp from any to any dst-port 82 in" \ 380 "ipfw -q add 100 allow tcp from any to any lookup dscp 1 in" \ 381 "ipfw -q add 200 unreach port tcp from any to any port 82 in" 382 atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82 383 384 firewall_config "alcatraz" ipfw ipfw \ 385 "ipfw -q table 1 create type number" \ 386 "ipfw -q table 1 add 13" \ 387 "ipfw -q add 50 setdscp 12 tcp from any to any dst-port 82 in" \ 388 "ipfw -q add 100 allow tcp from any to any lookup dscp 1 in" \ 389 "ipfw -q add 200 unreach port tcp from any to any dst-port 82 in" 390 atf_check -s exit:1 ${NC} 192.0.2.1 82 391 392 # Masked part 393 394 firewall_config "alcatraz" ipfw ipfw \ 395 "ipfw -q table 1 create type number" \ 396 "ipfw -q table 1 add 48" \ 397 "ipfw -q add 50 setdscp 50 tcp from any to any dst-port 82 in" \ 398 "ipfw -q add 100 allow tcp from any to any lookup dscp:0xF0 1 in" \ 399 "ipfw -q add 200 unreach port tcp from any to any dst-port 82" 400 atf_check -o "inline:GOOD 82\n" ${NC} 192.0.2.1 82 401 402 firewall_config "alcatraz" ipfw ipfw \ 403 "ipfw -q table 1 create type number" \ 404 "ipfw -q table 1 add 48" \ 405 "ipfw -q add 50 setdscp 50 tcp from any to any dst-port 82 in" \ 406 "ipfw -q add 100 allow tcp from any to any lookup dscp:255 1 in" \ 407 "ipfw -q add 200 unreach port tcp from any to any dst-port 82" 408 atf_check -s exit:1 ${NC} 192.0.2.1 82 409} 410 411 412lookup_cleanup() 413{ 414 firewall_cleanup $1 415} 416 417atf_init_test_cases() 418{ 419 for test in "ip4" "ip6" \ 420 "rulenum" "port" \ 421 "dscp_v4" "dscp_v6" \ 422 ; do 423 atf_add_test_case "${test}" 424 alias "${test}_cleanup"="lookup_cleanup" 425 done 426} 427 428