Home | History | Annotate | Line # | Download | only in arp
t_arp.sh revision 1.11
      1 #	$NetBSD: t_arp.sh,v 1.11 2016/02/25 03:23:15 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 
     28 inetserver="rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif"
     29 HIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=sysctl=yes"
     30 
     31 SOCKSRC=unix://commsock1
     32 SOCKDST=unix://commsock2
     33 IP4SRC=10.0.1.1
     34 IP4DST=10.0.1.2
     35 IP4DST_PUB=10.0.1.3
     36 MACDST_PUB=b2:a1:00:00:00:01
     37 IP4DST_PUBPROXY=10.0.1.4
     38 MACDST_PUBPROXY=b2:a1:00:00:00:02
     39 
     40 DEBUG=false
     41 TIMEOUT=1
     42 
     43 atf_test_case cache_expiration_5s cleanup
     44 atf_test_case cache_expiration_10s cleanup
     45 atf_test_case command cleanup
     46 atf_test_case garp cleanup
     47 atf_test_case cache_overwriting cleanup
     48 atf_test_case pubproxy_arp cleanup
     49 
     50 cache_expiration_5s_head()
     51 {
     52 	atf_set "descr" "Tests for ARP cache expiration (5s)"
     53 	atf_set "require.progs" "rump_server"
     54 }
     55 
     56 cache_expiration_10s_head()
     57 {
     58 	atf_set "descr" "Tests for ARP cache expiration (10s)"
     59 	atf_set "require.progs" "rump_server"
     60 }
     61 
     62 command_head()
     63 {
     64 	atf_set "descr" "Tests for commands of arp(8)"
     65 	atf_set "require.progs" "rump_server"
     66 }
     67 
     68 garp_head()
     69 {
     70 	atf_set "descr" "Tests for GARP"
     71 	atf_set "require.progs" "rump_server"
     72 }
     73 
     74 cache_overwriting_head()
     75 {
     76 	atf_set "descr" "Tests for behavior of overwriting ARP caches"
     77 	atf_set "require.progs" "rump_server"
     78 }
     79 
     80 pubproxy_arp_head()
     81 {
     82 	atf_set "descr" "Tests for Proxy ARP"
     83 	atf_set "require.progs" "rump_server"
     84 }
     85 
     86 setup_dst_server()
     87 {
     88 	export RUMP_SERVER=$SOCKDST
     89 	atf_check -s exit:0 rump.ifconfig shmif0 create
     90 	atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
     91 	atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4DST/24
     92 	atf_check -s exit:0 rump.ifconfig shmif0 up
     93 	atf_check -s exit:0 rump.ifconfig -w 10
     94 
     95 	$DEBUG && rump.ifconfig shmif0
     96 	$DEBUG && rump.arp -n -a
     97 }
     98 
     99 setup_src_server()
    100 {
    101 	local keep=$1
    102 
    103 	export RUMP_SERVER=$SOCKSRC
    104 
    105 	# Adjust ARP parameters
    106 	atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.arp.keep=$keep
    107 
    108 	# Setup an interface
    109 	atf_check -s exit:0 rump.ifconfig shmif0 create
    110 	atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
    111 	atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4SRC/24
    112 	atf_check -s exit:0 rump.ifconfig shmif0 up
    113 	atf_check -s exit:0 rump.ifconfig -w 10
    114 
    115 	# Sanity check
    116 	$DEBUG && rump.ifconfig shmif0
    117 	$DEBUG && rump.arp -n -a
    118 	atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC
    119 	atf_check -s not-exit:0 -e ignore rump.arp -n $IP4DST
    120 }
    121 
    122 test_cache_expiration()
    123 {
    124 	local arp_keep=$1
    125 	local bonus=2
    126 
    127 	atf_check -s exit:0 ${inetserver} $SOCKSRC
    128 	atf_check -s exit:0 ${inetserver} $SOCKDST
    129 
    130 	setup_dst_server
    131 	setup_src_server $arp_keep
    132 
    133 	#
    134 	# Check if a cache is expired expectedly
    135 	#
    136 	export RUMP_SERVER=$SOCKSRC
    137 	atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST
    138 
    139 	$DEBUG && rump.arp -n -a
    140 	atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC
    141 	# Should be cached
    142 	atf_check -s exit:0 -o ignore rump.arp -n $IP4DST
    143 
    144 	atf_check -s exit:0 sleep $(($arp_keep + $bonus))
    145 
    146 	$DEBUG && rump.arp -n -a
    147 	atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC
    148 	# Should be expired
    149 	atf_check -s not-exit:0 -e ignore rump.arp -n $IP4DST
    150 }
    151 
    152 cache_expiration_5s_body()
    153 {
    154 	test_cache_expiration 5
    155 }
    156 
    157 cache_expiration_10s_body()
    158 {
    159 	test_cache_expiration 10
    160 }
    161 
    162 command_body()
    163 {
    164 	local arp_keep=5
    165 	local bonus=2
    166 
    167 	atf_check -s exit:0 ${inetserver} $SOCKSRC
    168 	atf_check -s exit:0 ${inetserver} $SOCKDST
    169 
    170 	setup_dst_server
    171 	setup_src_server $arp_keep
    172 
    173 	export RUMP_SERVER=$SOCKSRC
    174 
    175 	# Add and delete a static entry
    176 	$DEBUG && rump.arp -n -a
    177 	atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10
    178 	$DEBUG && rump.arp -n -a
    179 	atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10
    180 	atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.10
    181 	atf_check -s exit:0 -o ignore rump.arp -d 10.0.1.10
    182 	$DEBUG && rump.arp -n -a
    183 	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10
    184 
    185 	# Add multiple entries via a file
    186 	cat - > ./list <<-EOF
    187 	10.0.1.11 b2:a0:20:00:00:11
    188 	10.0.1.12 b2:a0:20:00:00:12
    189 	10.0.1.13 b2:a0:20:00:00:13
    190 	10.0.1.14 b2:a0:20:00:00:14
    191 	10.0.1.15 b2:a0:20:00:00:15
    192 	EOF
    193 	$DEBUG && rump.arp -n -a
    194 	atf_check -s exit:0 -o ignore rump.arp -f ./list
    195 	$DEBUG && rump.arp -n -a
    196 	atf_check -s exit:0 -o match:'b2:a0:20:00:00:11' rump.arp -n 10.0.1.11
    197 	atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.11
    198 	atf_check -s exit:0 -o match:'b2:a0:20:00:00:12' rump.arp -n 10.0.1.12
    199 	atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.12
    200 	atf_check -s exit:0 -o match:'b2:a0:20:00:00:13' rump.arp -n 10.0.1.13
    201 	atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.13
    202 	atf_check -s exit:0 -o match:'b2:a0:20:00:00:14' rump.arp -n 10.0.1.14
    203 	atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.14
    204 	atf_check -s exit:0 -o match:'b2:a0:20:00:00:15' rump.arp -n 10.0.1.15
    205 	atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.15
    206 
    207 	# Test arp -a
    208 	atf_check -s exit:0 -o match:'10.0.1.11' rump.arp -n -a
    209 	atf_check -s exit:0 -o match:'10.0.1.12' rump.arp -n -a
    210 	atf_check -s exit:0 -o match:'10.0.1.13' rump.arp -n -a
    211 	atf_check -s exit:0 -o match:'10.0.1.14' rump.arp -n -a
    212 	atf_check -s exit:0 -o match:'10.0.1.15' rump.arp -n -a
    213 
    214 	# Flush all entries
    215 	$DEBUG && rump.arp -n -a
    216 	atf_check -s exit:0 -o ignore rump.arp -d -a
    217 	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.11
    218 	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.12
    219 	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.13
    220 	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.14
    221 	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.15
    222 	atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.1
    223 
    224 	# Test temp option
    225 	$DEBUG && rump.arp -n -a
    226 	atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp
    227 	$DEBUG && rump.arp -n -a
    228 	atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10
    229 	atf_check -s exit:0 -o not-match:'permanent' rump.arp -n 10.0.1.10
    230 
    231 	# Hm? the cache doesn't expire...
    232 	atf_check -s exit:0 sleep $(($arp_keep + $bonus))
    233 	$DEBUG && rump.arp -n -a
    234 	#atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10
    235 
    236 	return 0
    237 }
    238 
    239 make_pkt_str_arpreq()
    240 {
    241 	local target=$1
    242 	local sender=$2
    243 	pkt="> ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42:"
    244 	pkt="$pkt Request who-has $target tell $sender, length 28"
    245 	echo $pkt
    246 }
    247 
    248 garp_body()
    249 {
    250 	local pkt=
    251 
    252 	atf_check -s exit:0 ${inetserver} $SOCKSRC
    253 	export RUMP_SERVER=$SOCKSRC
    254 
    255 	# Setup an interface
    256 	atf_check -s exit:0 rump.ifconfig shmif0 create
    257 	atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
    258 	atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.1/24
    259 	atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.2/24 alias
    260 	atf_check -s exit:0 rump.ifconfig shmif0 up
    261 	$DEBUG && rump.ifconfig shmif0
    262 
    263 	atf_check -s exit:0 sleep 1
    264 	shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r - > ./out
    265 
    266 	# A GARP packet is sent for the primary address
    267 	pkt=$(make_pkt_str_arpreq 10.0.0.1 10.0.0.1)
    268 	atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
    269 	# No GARP packet is sent for the alias address
    270 	pkt=$(make_pkt_str_arpreq 10.0.0.2 10.0.0.2)
    271 	atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
    272 
    273 	atf_check -s exit:0 rump.ifconfig -w 10
    274 	atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.3/24
    275 	atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.4/24 alias
    276 
    277 	# No GARP packets are sent during IFF_UP
    278 	shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r - > ./out
    279 	pkt=$(make_pkt_str_arpreq 10.0.0.3 10.0.0.3)
    280 	atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
    281 	pkt=$(make_pkt_str_arpreq 10.0.0.4 10.0.0.4)
    282 	atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
    283 }
    284 
    285 cache_overwriting_body()
    286 {
    287 	local arp_keep=5
    288 	local bonus=2
    289 
    290 	atf_check -s exit:0 ${inetserver} $SOCKSRC
    291 	atf_check -s exit:0 ${inetserver} $SOCKDST
    292 
    293 	setup_dst_server
    294 	setup_src_server $arp_keep
    295 
    296 	export RUMP_SERVER=$SOCKSRC
    297 
    298 	# Cannot overwrite a permanent cache
    299 	atf_check -s not-exit:0 -e match:'File exists' \
    300 	    rump.arp -s $IP4SRC b2:a0:20:00:00:ff
    301 	$DEBUG && rump.arp -n -a
    302 
    303 	atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST
    304 	$DEBUG && rump.arp -n -a
    305 	# Can overwrite a dynamic cache
    306 	atf_check -s exit:0 -o ignore rump.arp -s $IP4DST b2:a0:20:00:00:00
    307 	$DEBUG && rump.arp -n -a
    308 	atf_check -s exit:0 -o match:'b2:a0:20:00:00:00' rump.arp -n $IP4DST
    309 	atf_check -s exit:0 -o match:'permanent' rump.arp -n $IP4DST
    310 
    311 	atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp
    312 	$DEBUG && rump.arp -n -a
    313 	atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10
    314 	atf_check -s exit:0 -o not-match:'permanent' rump.arp -n 10.0.1.10
    315 	# Cannot overwrite a temp cache
    316 	atf_check -s not-exit:0 -e match:'File exists' \
    317 	    rump.arp -s 10.0.1.10 b2:a0:20:00:00:ff
    318 	$DEBUG && rump.arp -n -a
    319 
    320 	return 0
    321 }
    322 
    323 make_pkt_str_arprep()
    324 {
    325 	local ip=$1
    326 	local mac=$2
    327 	pkt="ethertype ARP (0x0806), length 42: "
    328 	pkt="Reply $ip is-at $mac, length 28"
    329 	echo $pkt
    330 }
    331 
    332 extract_new_packets()
    333 {
    334 	local old=./old
    335 
    336 	if [ ! -f $old ]; then
    337 		old=/dev/null
    338 	fi
    339 
    340 	shmif_dumpbus -p - bus1 2>/dev/null| \
    341 	    tcpdump -n -e -r - 2>/dev/null > ./new
    342 	diff -u $old ./new |grep '^+' |cut -d '+' -f 2 > ./diff
    343 	mv -f ./new ./old
    344 	cat ./diff
    345 }
    346 
    347 check_entry_flags()
    348 {
    349 	local ip=$(echo $1 |sed 's/\./\\./g')
    350 	local flags=$2
    351 
    352 	atf_check -s exit:0 -o match:" $flags " -e ignore -x \
    353 	    "rump.netstat -rn -f inet | grep ^'$ip'"
    354 }
    355 
    356 pubproxy_arp_body()
    357 {
    358 	local arp_keep=5
    359 
    360 	atf_check -s exit:0 ${inetserver} $SOCKSRC
    361 	atf_check -s exit:0 ${inetserver} $SOCKDST
    362 
    363 	setup_dst_server
    364 	setup_src_server $arp_keep
    365 
    366 	export RUMP_SERVER=$SOCKDST
    367 
    368 	atf_check -s exit:0 -o ignore rump.arp -s $IP4DST_PUB \
    369 	    $MACDST_PUB pub
    370 	atf_check -s exit:0 -o match:'permanent published' \
    371 	    rump.arp -n $IP4DST_PUB
    372 	check_entry_flags $IP4DST_PUB ULSp
    373 
    374 	$DEBUG && rump.arp -n -a
    375 	$DEBUG && rump.netstat -nr -f inet
    376 
    377 	atf_check -s exit:0 -o ignore rump.arp -s $IP4DST_PUBPROXY \
    378 	    $MACDST_PUBPROXY pub proxy
    379 	atf_check -s exit:0 -o match:'permanent published \(proxy only\)' \
    380 	    rump.arp -n $IP4DST_PUBPROXY
    381 	check_entry_flags $IP4DST_PUBPROXY UHLSp
    382 
    383 	$DEBUG && rump.arp -n -a
    384 	$DEBUG && rump.netstat -nr -f inet
    385 
    386 	export RUMP_SERVER=$SOCKSRC
    387 
    388 	atf_check -s not-exit:0 -o ignore -e ignore \
    389 	    rump.ping -n -w 1 -c 1 $IP4DST_PUB
    390 
    391 	atf_check -s exit:0 sleep 1
    392 	extract_new_packets > ./out
    393 	$DEBUG && cat ./out
    394 
    395 	pkt=$(make_pkt_str_arprep $IP4DST_PUB $MACDST_PUB)
    396 	atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
    397 
    398 	atf_check -s not-exit:0 -o ignore -e ignore \
    399 	    rump.ping -n -w 1 -c 1 $IP4DST_PUBPROXY
    400 
    401 	atf_check -s exit:0 sleep 1
    402 	extract_new_packets > ./out
    403 	$DEBUG && cat ./out
    404 
    405 	pkt=$(make_pkt_str_arprep $IP4DST_PUBPROXY $MACDST_PUBPROXY)
    406 	atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
    407 
    408 	return 0
    409 }
    410 
    411 cleanup()
    412 {
    413 	env RUMP_SERVER=$SOCKSRC rump.halt
    414 	env RUMP_SERVER=$SOCKDST rump.halt
    415 }
    416 
    417 dump_src()
    418 {
    419 	export RUMP_SERVER=$SOCKSRC
    420 	rump.netstat -nr
    421 	rump.arp -n -a
    422 	rump.ifconfig
    423 	$HIJACKING dmesg
    424 }
    425 
    426 dump_dst()
    427 {
    428 	export RUMP_SERVER=$SOCKDST
    429 	rump.netstat -nr
    430 	rump.arp -n -a
    431 	rump.ifconfig
    432 	$HIJACKING dmesg
    433 }
    434 
    435 dump()
    436 {
    437 	dump_src
    438 	dump_dst
    439 	shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r -
    440 }
    441 
    442 cache_expiration_5s_cleanup()
    443 {
    444 	$DEBUG && dump
    445 	cleanup
    446 }
    447 
    448 cache_expiration_10s_cleanup()
    449 {
    450 	$DEBUG && dump
    451 	cleanup
    452 }
    453 
    454 command_cleanup()
    455 {
    456 	$DEBUG && dump
    457 	cleanup
    458 }
    459 
    460 garp_cleanup()
    461 {
    462 	$DEBUG && dump_src
    463 	$DEBUG && shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r -
    464 	env RUMP_SERVER=$SOCKSRC rump.halt
    465 }
    466 
    467 cache_overwriting_cleanup()
    468 {
    469 	$DEBUG && dump
    470 	cleanup
    471 }
    472 
    473 pubproxy_arp_cleanup()
    474 {
    475 	$DEBUG && dump
    476 	cleanup
    477 }
    478 
    479 atf_init_test_cases()
    480 {
    481 	atf_add_test_case cache_expiration_5s
    482 	atf_add_test_case cache_expiration_10s
    483 	atf_add_test_case command
    484 	atf_add_test_case garp
    485 	atf_add_test_case cache_overwriting
    486 	atf_add_test_case pubproxy_arp
    487 }
    488