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