1# $NetBSD: t_arp.sh,v 1.22 2016/11/25 08:51:16 ozaki-r Exp $ 2# 3# Copyright (c) 2015 The NetBSD Foundation, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27 28SOCKSRC=unix://commsock1 29SOCKDST=unix://commsock2 30IP4SRC=10.0.1.1 31IP4DST=10.0.1.2 32IP4DST_PROXYARP1=10.0.1.3 33IP4DST_PROXYARP2=10.0.1.4 34 35DEBUG=${DEBUG:-false} 36TIMEOUT=1 37 38atf_test_case arp_cache_expiration_5s cleanup 39atf_test_case arp_cache_expiration_10s cleanup 40atf_test_case arp_command cleanup 41atf_test_case arp_garp cleanup 42atf_test_case arp_cache_overwriting cleanup 43atf_test_case arp_proxy_arp_pub cleanup 44atf_test_case arp_proxy_arp_pubproxy cleanup 45atf_test_case arp_link_activation cleanup 46atf_test_case arp_static cleanup 47 48arp_cache_expiration_5s_head() 49{ 50 atf_set "descr" "Tests for ARP cache expiration (5s)" 51 atf_set "require.progs" "rump_server" 52} 53 54arp_cache_expiration_10s_head() 55{ 56 atf_set "descr" "Tests for ARP cache expiration (10s)" 57 atf_set "require.progs" "rump_server" 58} 59 60arp_command_head() 61{ 62 atf_set "descr" "Tests for arp_commands of arp(8)" 63 atf_set "require.progs" "rump_server" 64} 65 66arp_garp_head() 67{ 68 atf_set "descr" "Tests for GARP" 69 atf_set "require.progs" "rump_server" 70} 71 72arp_cache_overwriting_head() 73{ 74 atf_set "descr" "Tests for behavior of overwriting ARP caches" 75 atf_set "require.progs" "rump_server" 76} 77 78arp_proxy_arp_pub_head() 79{ 80 atf_set "descr" "Tests for Proxy ARP (pub)" 81 atf_set "require.progs" "rump_server" 82} 83 84arp_proxy_arp_pubproxy_head() 85{ 86 atf_set "descr" "Tests for Proxy ARP (pub proxy)" 87 atf_set "require.progs" "rump_server" 88} 89 90arp_link_activation_head() 91{ 92 atf_set "descr" "Tests for activating a new MAC address" 93 atf_set "require.progs" "rump_server" 94} 95 96arp_static_head() 97{ 98 99 atf_set "descr" "Tests for static ARP entries" 100 atf_set "require.progs" "rump_server" 101} 102 103setup_dst_server() 104{ 105 106 rump_server_add_iface $SOCKDST shmif0 bus1 107 export RUMP_SERVER=$SOCKDST 108 atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4DST/24 109 atf_check -s exit:0 rump.ifconfig shmif0 up 110 atf_check -s exit:0 rump.ifconfig -w 10 111 112 $DEBUG && rump.ifconfig shmif0 113 $DEBUG && rump.arp -n -a 114} 115 116setup_src_server() 117{ 118 local keep=$1 119 120 export RUMP_SERVER=$SOCKSRC 121 122 # Adjust ARP parameters 123 atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.arp.keep=$keep 124 125 # Setup an interface 126 rump_server_add_iface $SOCKSRC shmif0 bus1 127 atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4SRC/24 128 atf_check -s exit:0 rump.ifconfig shmif0 up 129 atf_check -s exit:0 rump.ifconfig -w 10 130 131 # Sanity check 132 $DEBUG && rump.ifconfig shmif0 133 $DEBUG && rump.arp -n -a 134 atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC 135 atf_check -s not-exit:0 -e ignore rump.arp -n $IP4DST 136} 137 138test_cache_expiration() 139{ 140 local arp_keep=$1 141 local bonus=2 142 143 rump_server_start $SOCKSRC 144 rump_server_start $SOCKDST 145 146 setup_dst_server 147 setup_src_server $arp_keep 148 149 # 150 # Check if a cache is expired expectedly 151 # 152 export RUMP_SERVER=$SOCKSRC 153 atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST 154 155 $DEBUG && rump.arp -n -a 156 atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC 157 # Should be cached 158 atf_check -s exit:0 -o ignore rump.arp -n $IP4DST 159 160 atf_check -s exit:0 sleep $(($arp_keep + $bonus)) 161 162 $DEBUG && rump.arp -n -a 163 atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC 164 # Should be expired 165 atf_check -s not-exit:0 -e ignore rump.arp -n $IP4DST 166} 167 168arp_cache_expiration_5s_body() 169{ 170 171 test_cache_expiration 5 172 rump_server_destroy_ifaces 173} 174 175arp_cache_expiration_10s_body() 176{ 177 178 test_cache_expiration 10 179 rump_server_destroy_ifaces 180} 181 182arp_command_body() 183{ 184 local arp_keep=5 185 local bonus=2 186 187 rump_server_start $SOCKSRC 188 rump_server_start $SOCKDST 189 190 setup_dst_server 191 setup_src_server $arp_keep 192 193 export RUMP_SERVER=$SOCKSRC 194 195 # We can delete the entry for the interface's IP address 196 atf_check -s exit:0 -o ignore rump.arp -d $IP4SRC 197 198 # Add and delete a static entry 199 $DEBUG && rump.arp -n -a 200 atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 201 $DEBUG && rump.arp -n -a 202 atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10 203 atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.10 204 atf_check -s exit:0 -o ignore rump.arp -d 10.0.1.10 205 $DEBUG && rump.arp -n -a 206 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10 207 208 # Add multiple entries via a file 209 cat - > ./list <<-EOF 210 10.0.1.11 b2:a0:20:00:00:11 211 10.0.1.12 b2:a0:20:00:00:12 212 10.0.1.13 b2:a0:20:00:00:13 213 10.0.1.14 b2:a0:20:00:00:14 214 10.0.1.15 b2:a0:20:00:00:15 215 EOF 216 $DEBUG && rump.arp -n -a 217 atf_check -s exit:0 -o ignore rump.arp -f ./list 218 $DEBUG && rump.arp -n -a 219 atf_check -s exit:0 -o match:'b2:a0:20:00:00:11' rump.arp -n 10.0.1.11 220 atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.11 221 atf_check -s exit:0 -o match:'b2:a0:20:00:00:12' rump.arp -n 10.0.1.12 222 atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.12 223 atf_check -s exit:0 -o match:'b2:a0:20:00:00:13' rump.arp -n 10.0.1.13 224 atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.13 225 atf_check -s exit:0 -o match:'b2:a0:20:00:00:14' rump.arp -n 10.0.1.14 226 atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.14 227 atf_check -s exit:0 -o match:'b2:a0:20:00:00:15' rump.arp -n 10.0.1.15 228 atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.15 229 230 # Test arp -a 231 atf_check -s exit:0 -o match:'10.0.1.11' rump.arp -n -a 232 atf_check -s exit:0 -o match:'10.0.1.12' rump.arp -n -a 233 atf_check -s exit:0 -o match:'10.0.1.13' rump.arp -n -a 234 atf_check -s exit:0 -o match:'10.0.1.14' rump.arp -n -a 235 atf_check -s exit:0 -o match:'10.0.1.15' rump.arp -n -a 236 237 # Flush all entries 238 $DEBUG && rump.arp -n -a 239 atf_check -s exit:0 -o ignore rump.arp -d -a 240 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.11 241 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.12 242 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.13 243 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.14 244 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.15 245 atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.1 246 247 # Test temp option 248 $DEBUG && rump.arp -n -a 249 atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp 250 $DEBUG && rump.arp -n -a 251 atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10 252 atf_check -s exit:0 -o not-match:'permanent' rump.arp -n 10.0.1.10 253 254 # Hm? the cache doesn't expire... 255 atf_check -s exit:0 sleep $(($arp_keep + $bonus)) 256 $DEBUG && rump.arp -n -a 257 #atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10 258 259 rump_server_destroy_ifaces 260} 261 262make_pkt_str_arpreq() 263{ 264 local target=$1 265 local sender=$2 266 pkt="> ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42:" 267 pkt="$pkt Request who-has $target tell $sender, length 28" 268 echo $pkt 269} 270 271arp_garp_body() 272{ 273 local pkt= 274 275 rump_server_start $SOCKSRC 276 277 export RUMP_SERVER=$SOCKSRC 278 279 # Setup an interface 280 rump_server_add_iface $SOCKSRC shmif0 bus1 281 atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.1/24 282 atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.2/24 alias 283 atf_check -s exit:0 rump.ifconfig shmif0 up 284 $DEBUG && rump.ifconfig shmif0 285 286 atf_check -s exit:0 sleep 1 287 shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r - > ./out 288 289 # A GARP packet is sent for the primary address 290 pkt=$(make_pkt_str_arpreq 10.0.0.1 10.0.0.1) 291 atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" 292 # No GARP packet is sent for the alias address 293 pkt=$(make_pkt_str_arpreq 10.0.0.2 10.0.0.2) 294 atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" 295 296 atf_check -s exit:0 rump.ifconfig -w 10 297 atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.3/24 298 atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.4/24 alias 299 300 # No GARP packets are sent during IFF_UP 301 shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r - > ./out 302 pkt=$(make_pkt_str_arpreq 10.0.0.3 10.0.0.3) 303 atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" 304 pkt=$(make_pkt_str_arpreq 10.0.0.4 10.0.0.4) 305 atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" 306 307 rump_server_destroy_ifaces 308} 309 310arp_cache_overwriting_body() 311{ 312 local arp_keep=5 313 local bonus=2 314 315 rump_server_start $SOCKSRC 316 rump_server_start $SOCKDST 317 318 setup_dst_server 319 setup_src_server $arp_keep 320 321 export RUMP_SERVER=$SOCKSRC 322 323 # Cannot overwrite a permanent cache 324 atf_check -s not-exit:0 -e match:'File exists' \ 325 rump.arp -s $IP4SRC b2:a0:20:00:00:ff 326 $DEBUG && rump.arp -n -a 327 328 atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST 329 $DEBUG && rump.arp -n -a 330 # Can overwrite a dynamic cache 331 atf_check -s exit:0 -o ignore rump.arp -s $IP4DST b2:a0:20:00:00:00 332 $DEBUG && rump.arp -n -a 333 atf_check -s exit:0 -o match:'b2:a0:20:00:00:00' rump.arp -n $IP4DST 334 atf_check -s exit:0 -o match:'permanent' rump.arp -n $IP4DST 335 336 atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp 337 $DEBUG && rump.arp -n -a 338 atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10 339 atf_check -s exit:0 -o not-match:'permanent' rump.arp -n 10.0.1.10 340 # Can overwrite a temp cache 341 atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:ff 342 atf_check -s exit:0 -o match:'b2:a0:20:00:00:ff' rump.arp -n 10.0.1.10 343 $DEBUG && rump.arp -n -a 344 345 rump_server_destroy_ifaces 346} 347 348make_pkt_str_arprep() 349{ 350 local ip=$1 351 local mac=$2 352 pkt="ethertype ARP (0x0806), length 42: " 353 pkt="Reply $ip is-at $mac, length 28" 354 echo $pkt 355} 356 357make_pkt_str_garp() 358{ 359 local ip=$1 360 local mac=$2 361 local pkt= 362 pkt="$mac > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806)," 363 pkt="$pkt length 42: Request who-has $ip tell $ip, length 28" 364 echo $pkt 365} 366 367test_proxy_arp() 368{ 369 local arp_keep=5 370 local opts= title= flags= 371 local type=$1 372 373 rump_server_start $SOCKSRC 374 rump_server_start $SOCKDST tap 375 376 setup_dst_server 377 setup_src_server $arp_keep 378 379 export RUMP_SERVER=$SOCKDST 380 atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=1 381 macaddr_dst=$(get_macaddr $SOCKDST shmif0) 382 383 if [ "$type" = "pub" ]; then 384 opts="pub" 385 title="permanent published" 386 else 387 opts="pub proxy" 388 title='permanent published \(proxy only\)' 389 fi 390 391 # 392 # Test#1: First setup an endpoint then create proxy arp entry 393 # 394 export RUMP_SERVER=$SOCKDST 395 atf_check -s exit:0 rump.ifconfig tap1 create 396 atf_check -s exit:0 rump.ifconfig tap1 $IP4DST_PROXYARP1/24 up 397 atf_check -s exit:0 rump.ifconfig -w 10 398 399 # Try to ping (should fail w/o proxy arp) 400 export RUMP_SERVER=$SOCKSRC 401 atf_check -s not-exit:0 -o ignore -e ignore \ 402 rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1 403 404 # Flushing 405 extract_new_packets bus1 > ./out 406 407 # Set up proxy ARP entry 408 export RUMP_SERVER=$SOCKDST 409 atf_check -s exit:0 -o ignore \ 410 rump.arp -s $IP4DST_PROXYARP1 $macaddr_dst $opts 411 atf_check -s exit:0 -o match:"$title" rump.arp -n $IP4DST_PROXYARP1 412 413 # Try to ping 414 export RUMP_SERVER=$SOCKSRC 415 if [ "$type" = "pub" ]; then 416 # XXX fails 417 atf_check -s not-exit:0 -o ignore -e ignore \ 418 rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1 419 else 420 atf_check -s exit:0 -o ignore \ 421 rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1 422 fi 423 424 extract_new_packets bus1 > ./out 425 $DEBUG && cat ./out 426 427 pkt1=$(make_pkt_str_arprep $IP4DST_PROXYARP1 $macaddr_dst) 428 pkt2=$(make_pkt_str_garp $IP4DST_PROXYARP1 $macaddr_dst) 429 if [ "$type" = "pub" ]; then 430 atf_check -s not-exit:0 -x \ 431 "cat ./out |grep -q -e '$pkt1' -e '$pkt2'" 432 else 433 atf_check -s exit:0 -x "cat ./out |grep -q -e '$pkt1' -e '$pkt2'" 434 fi 435 436 # 437 # Test#2: Create proxy arp entry then set up an endpoint 438 # 439 export RUMP_SERVER=$SOCKDST 440 atf_check -s exit:0 -o ignore \ 441 rump.arp -s $IP4DST_PROXYARP2 $macaddr_dst $opts 442 atf_check -s exit:0 -o match:"$title" rump.arp -n $IP4DST_PROXYARP2 443 $DEBUG && rump.netstat -nr -f inet 444 445 # Try to ping (should fail because no endpoint exists) 446 export RUMP_SERVER=$SOCKSRC 447 atf_check -s not-exit:0 -o ignore -e ignore \ 448 rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2 449 450 extract_new_packets bus1 > ./out 451 $DEBUG && cat ./out 452 453 # ARP reply should be sent 454 pkt=$(make_pkt_str_arprep $IP4DST_PROXYARP2 $macaddr_dst) 455 atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" 456 457 export RUMP_SERVER=$SOCKDST 458 atf_check -s exit:0 rump.ifconfig tap2 create 459 atf_check -s exit:0 rump.ifconfig tap2 $IP4DST_PROXYARP2/24 up 460 atf_check -s exit:0 rump.ifconfig -w 10 461 462 # Try to ping 463 export RUMP_SERVER=$SOCKSRC 464 atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2 465} 466 467arp_proxy_arp_pub_body() 468{ 469 470 test_proxy_arp pub 471 rump_server_destroy_ifaces 472} 473 474arp_proxy_arp_pubproxy_body() 475{ 476 477 test_proxy_arp pubproxy 478 rump_server_destroy_ifaces 479} 480 481arp_link_activation_body() 482{ 483 local arp_keep=5 484 local bonus=2 485 486 rump_server_start $SOCKSRC 487 rump_server_start $SOCKDST 488 489 setup_dst_server 490 setup_src_server $arp_keep 491 492 # flush old packets 493 extract_new_packets bus1 > ./out 494 495 export RUMP_SERVER=$SOCKSRC 496 497 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ 498 b2:a1:00:00:00:01 499 500 atf_check -s exit:0 sleep 1 501 extract_new_packets bus1 > ./out 502 $DEBUG && cat ./out 503 504 pkt=$(make_pkt_str_arpreq $IP4SRC $IP4SRC) 505 atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" 506 507 atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ 508 b2:a1:00:00:00:02 active 509 510 atf_check -s exit:0 sleep 1 511 extract_new_packets bus1 > ./out 512 $DEBUG && cat ./out 513 514 pkt=$(make_pkt_str_arpreq $IP4SRC $IP4SRC) 515 atf_check -s exit:0 -x \ 516 "cat ./out |grep '$pkt' |grep -q 'b2:a1:00:00:00:02'" 517 518 rump_server_destroy_ifaces 519} 520 521arp_static_body() 522{ 523 local arp_keep=5 524 local macaddr_src= 525 526 rump_server_start $SOCKSRC 527 rump_server_start $SOCKDST 528 529 setup_dst_server 530 setup_src_server $arp_keep 531 532 macaddr_src=$(get_macaddr $SOCKSRC shmif0) 533 534 # Set a (valid) static ARP entry for the src server 535 export RUMP_SERVER=$SOCKDST 536 $DEBUG && rump.arp -n -a 537 atf_check -s exit:0 -o ignore rump.arp -s $IP4SRC $macaddr_src 538 $DEBUG && rump.arp -n -a 539 540 # Test receiving an ARP request with the static ARP entry (as spa/sha) 541 export RUMP_SERVER=$SOCKSRC 542 atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST 543 544 rump_server_destroy_ifaces 545} 546 547arp_cache_expiration_5s_cleanup() 548{ 549 $DEBUG && dump 550 cleanup 551} 552 553arp_cache_expiration_10s_cleanup() 554{ 555 $DEBUG && dump 556 cleanup 557} 558 559arp_command_cleanup() 560{ 561 $DEBUG && dump 562 cleanup 563} 564 565arp_garp_cleanup() 566{ 567 $DEBUG && dump 568 cleanup 569} 570 571arp_cache_overwriting_cleanup() 572{ 573 $DEBUG && dump 574 cleanup 575} 576 577arp_proxy_arp_pub_cleanup() 578{ 579 $DEBUG && dump 580 cleanup 581} 582 583arp_proxy_arp_pubproxy_cleanup() 584{ 585 $DEBUG && dump 586 cleanup 587} 588 589arp_link_activation_cleanup() 590{ 591 $DEBUG && dump 592 cleanup 593} 594 595arp_static_cleanup() 596{ 597 $DEBUG && dump 598 cleanup 599} 600 601atf_init_test_cases() 602{ 603 atf_add_test_case arp_cache_expiration_5s 604 atf_add_test_case arp_cache_expiration_10s 605 atf_add_test_case arp_command 606 atf_add_test_case arp_garp 607 atf_add_test_case arp_cache_overwriting 608 atf_add_test_case arp_proxy_arp_pub 609 atf_add_test_case arp_proxy_arp_pubproxy 610 atf_add_test_case arp_link_activation 611 atf_add_test_case arp_static 612} 613