xref: /openbsd/regress/sys/net/pf_forward/Makefile (revision 274d7c50)
1#	$OpenBSD: Makefile,v 1.28 2019/05/10 02:22:34 bluhm Exp $
2
3# The following ports must be installed:
4#
5# python-2.7          interpreted object-oriented programming language
6# scapy               powerful interactive packet manipulation in python
7
8.if ! exists(/usr/local/bin/python2.7) || ! exists(/usr/local/bin/scapy)
9regress:
10	@echo install python and the scapy module for additional tests
11	@echo SKIPPED
12.endif
13
14# This test needs a manual setup of four machines
15# The setup is the same as for regress/sys/net/pf_fragment
16# Set up machines: SRC PF RT ECO
17# SRC is the machine where this makefile is running.
18# PF is running OpenBSD forwarding through pf, it is the test target.
19# RT is a router forwarding packets, maximum MTU is 1300.
20# ECO is reflecting the ping and UDP and TCP echo packets.
21# RDR does not exist, PF redirects the traffic to ECO.
22# AF does not exist, PF translates address family and sends to ECO.
23# RTT addresses exist on ECO, PF has no route and must use route-to RT
24# RPT addresses exist on SRC, PF has no route and must use reply-to SRC
25#
26# +---+   1   +--+   2   +--+   3   +---+ 4
27# |SRC| ----> |PF| ----> |RT| ----> |ECO| 7
28# +---+ 8     +--+       +--+       +---+ 9
29#     out    in  out    in  out    in   out
30#
31# 5 +---+ 6   7 +--+    8 +---+ 9   10 +---+ 11
32#   |RDR|       |AF|      |RTT|        |RPT|
33#   +---+       +--+      +---+        +---+
34#  in   out    in        in          out
35
36# Configure Addresses on the machines, there must be routes for the
37# networks.  Adapt interface and addresse variables to your local
38# setup.  To control the remote machine you need a hostname for
39# ssh to log in.
40# You must have an anchor "regress" for the divert rules in the pf.conf
41# of the PF machine.  The kernel of the PF machine gets testet.
42#
43# Run make check-setup to see if you got the setup correct.
44
45SRC_IF ?=	tap0
46SRC_MAC ?=	fe:e1:ba:d1:0a:dc
47PF_IFIN ?=	vio0
48PF_IFOUT ?=	vio1
49PF_MAC ?=	52:54:00:12:34:50
50PF_SSH ?=
51RT_SSH ?=
52ECO_SSH ?=
53
54SRC_OUT ?=	10.188.210.10
55PF_IN ?=	10.188.210.50
56PF_OUT ?=	10.188.211.50
57RT_IN ?=	10.188.211.51
58RT_OUT ?=	10.188.212.51
59ECO_IN ?=	10.188.212.52
60ECO_OUT ?=	10.188.213.52
61RDR_IN ?=	10.188.214.188
62RDR_OUT ?=	10.188.215.188
63AF_IN ?=	10.188.216.82		# /24 must be dec(ECO_IN6/120)
64RTT_IN ?=	10.188.217.52
65RTT_OUT ?=	10.188.218.52
66RPT_IN ?=	10.188.220.10
67RPT_OUT ?=	10.188.221.10
68
69SRC_OUT6 ?=	fdd7:e83e:66bc:210:fce1:baff:fed1:561f
70PF_IN6 ?=	fdd7:e83e:66bc:210:5054:ff:fe12:3450
71PF_OUT6 ?=	fdd7:e83e:66bc:211:5054:ff:fe12:3450
72RT_IN6 ?=	fdd7:e83e:66bc:211:5054:ff:fe12:3451
73RT_OUT6 ?=	fdd7:e83e:66bc:212:5054:ff:fe12:3451
74ECO_IN6 ?=	fdd7:e83e:66bc:212:5054:ff:fe12:3452
75ECO_OUT6 ?=	fdd7:e83e:66bc:213:5054:ff:fe12:3452
76RDR_IN6 ?=	fdd7:e83e:66bc:214::188
77RDR_OUT6 ?=	fdd7:e83e:66bc:215::188
78AF_IN6 ?=	fdd7:e83e:66bc:216::34	# /120 must be hex(ECO_IN/24)
79RTT_IN6 ?=	fdd7:e83e:66bc:217:5054:ff:fe12:3452
80RTT_OUT6 ?=	fdd7:e83e:66bc:218:5054:ff:fe12:3452
81RPT_IN6 ?=	fdd7:e83e:66bc:1220:fce1:baff:fed1:561f
82RPT_OUT6 ?=	fdd7:e83e:66bc:1221:fce1:baff:fed1:561f
83
84.if empty (PF_SSH) || empty (RT_SSH) || empty (ECO_SSH)
85regress:
86	@echo this tests needs three remote machines to operate on
87	@echo PF_SSH RT_SSH ECO_SSH are empty
88	@echo fill out these variables for additional tests, then
89	@echo check wether your test machines are set up properly
90	@echo SKIPPED
91.endif
92
93.MAIN: all
94
95.if ! empty (PF_SSH)
96.if make (regress) || make (all)
97.BEGIN: pf.conf addr.py
98	@echo
99	${SUDO} true
100	ssh -t ${PF_SSH} ${SUDO} true
101	rm -f stamp-pfctl
102.endif
103.endif
104
105# Create python include file containing the addresses.
106addr.py: Makefile
107	rm -f $@ $@.tmp
108	echo 'SRC_IF="${SRC_IF}"' >>$@.tmp
109	echo 'SRC_MAC="${SRC_MAC}"' >>$@.tmp
110	echo 'PF_IFIN="${PF_IFIN}"' >>$@.tmp
111	echo 'PF_IFOUT="${PF_IFOUT}"' >>$@.tmp
112	echo 'PF_MAC="${PF_MAC}"' >>$@.tmp
113.for var in SRC_OUT PF_IN PF_OUT RT_IN RT_OUT ECO_IN ECO_OUT RDR_IN RDR_OUT\
114    AF_IN RTT_IN RTT_OUT RPT_IN RPT_OUT
115	echo '${var}="${${var}}"' >>$@.tmp
116	echo '${var}6="${${var}6}"' >>$@.tmp
117.endfor
118	mv $@.tmp $@
119
120# Load the pf rules into the kernel of the PF machine.
121# XXX pfctl does not replace variables after @.
122stamp-pfctl: addr.py pf.conf
123	cat addr.py ${.CURDIR}/pf.conf | pfctl -n -f -
124	cat addr.py ${.CURDIR}/pf.conf | \
125	    sed 's/@$$PF_IFIN /@${PF_IFIN} /;s/@$$PF_IFOUT /@${PF_IFOUT} /' | \
126	    ssh ${PF_SSH} ${SUDO} pfctl -a regress -f -
127	@date >$@
128
129# Set variables so that make runs with and without obj directory.
130# Only do that if necessary to keep visible output short.
131.if ${.CURDIR} == ${.OBJDIR}
132PYTHON =	python2.7 -u ./
133.else
134PYTHON =	PYTHONPATH=${.OBJDIR} python2.7 -u ${.CURDIR}/
135.endif
136
137.for inet in inet inet6
138
139run-ping-mtu-1400-${inet}-RPT_OUT:
140	@echo '\n======== $@ ========'
141	# RPT_OUT with locally generated ICMP time exceeded cannot work.
142	# The generated packet will not match the out rule with reply-to
143	# so it will be rejected by the route.
144	@echo DISABLED
145
146.for proto in icmp udp
147run-traceroute-${proto}-${inet}-RPT_OUT:
148	@echo '\n======== $@ ========'
149	# RPT_OUT traceroute cannot work.  The ICMP time exceeded packet
150	# generated by IP forward will not match the out rule with reply-to
151	# so it will be rejected by the route.
152	@echo DISABLED
153.endfor # proto
154
155# Ping all addresses.  This ensures that the IP addresses are configured
156# and all routing table are set up to allow bidirectional packet flow.
157# Note that RDR does not exist physically.  So this traffic is rewritten
158# by PF and handled by ECO.
159
160.for ip in SRC_OUT PF_IN PF_OUT RT_IN RT_OUT ECO_IN ECO_OUT RDR_IN RDR_OUT\
161    AF_IN RTT_IN RTT_OUT RPT_IN RPT_OUT
162REGRESS_TARGETS +=	run-ping-${inet}-${ip}
163run-ping-${inet}-${ip}: stamp-pfctl
164	@echo '\n======== $@ ========'
165	@echo Check ping ${ip}${inet:S/inet//}:
166.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
167	ping${inet:S/inet//} -n -c 1 -I ${${ip}${inet:S/inet//}}\
168	    ${ECO_IN${inet:S/inet//}}
169.else
170	ping${inet:S/inet//} -n -c 1 ${${ip}${inet:S/inet//}}
171.endif
172.endfor # ip
173
174.for ip in ECO_IN ECO_OUT RDR_IN RDR_OUT AF_IN RTT_IN RTT_OUT RPT_IN RPT_OUT
175
176# Send a large IPv4/ICMP-Echo-Request packet with enabled DF bit and
177# parse response packet to determine MTU of the packet filter.  The
178# outgoing MTU of PF has to be 1400 octets.  Packet size is 1500.
179# Check that the IP length of the original packet and the ICMP
180# quoted packet are the same.
181
182REGRESS_TARGETS +=	run-ping-mtu-1400-${inet}-${ip}
183run-ping-mtu-1400-${inet}-${ip}: stamp-pfctl
184	@echo '\n======== $@ ========'
185	@echo Check path MTU to ${ip}${inet:S/inet//} is 1400
186.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
187	${SUDO} ${PYTHON}ping${inet:S/inet//}_mtu.py ${${ip}${inet:S/inet//}}\
188	    ${ECO_IN${inet:S/inet//}} 1500 1400
189.elif "AF_IN" == ${ip}
190.if "inet" == ${inet}
191	${SUDO} ${PYTHON}ping_mtu.py ${SRC_OUT} ${${ip}} 1500 1380
192.else
193	${SUDO} ${PYTHON}ping6_mtu.py ${SRC_OUT6} ${${ip}6} 1500 1420
194.endif
195.else
196	${SUDO} ${PYTHON}ping${inet:S/inet//}_mtu.py ${SRC_OUT${inet:S/inet//}}\
197	    ${${ip}${inet:S/inet//}} 1500 1400
198.endif
199
200# Send a large IPv4/ICMP-Echo-Request packet with enabled DF bit and
201# parse response packet to determine MTU of the router.  The MTU has
202# to be 1300 octets.  The MTU has to be defined at out interface of
203# the router RT before.  Packet size is 1400 to pass PF MTU.
204# Check that the IP length of the original packet and the ICMP
205# quoted packet are the same.
206
207REGRESS_TARGETS +=	run-ping-mtu-1300-${inet}-${ip}
208run-ping-mtu-1300-${inet}-${ip}: stamp-pfctl
209	@echo '\n======== $@ ========'
210	@echo Check path MTU from ${ip}${inet:S/inet//} is 1300
211.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
212	${SUDO} ${PYTHON}ping${inet:S/inet//}_mtu.py ${${ip}${inet:S/inet//}}\
213	    ${ECO_IN${inet:S/inet//}} 1400 1300
214.elif "AF_IN" == ${ip}
215.if "inet" == ${inet}
216	${SUDO} ${PYTHON}ping_mtu.py ${SRC_OUT} ${${ip}} 1380 1280
217.else
218	${SUDO} ${PYTHON}ping6_mtu.py ${SRC_OUT6} ${${ip}6} 1420 1320
219.endif
220.else
221	${SUDO} ${PYTHON}ping${inet:S/inet//}_mtu.py ${SRC_OUT${inet:S/inet//}}\
222	    ${${ip}${inet:S/inet//}} 1400 1300
223.endif
224
225# Send one UDP echo port 7 packet to all destination addresses with netcat.
226# The response must arrive in 1 second.
227
228REGRESS_TARGETS +=	run-udp-${inet}-${ip}
229run-udp-${inet}-${ip}: stamp-pfctl
230	@echo '\n======== $@ ========'
231	@echo Check UDP ${ip${inet:S/inet//}}:
232.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
233	echo $$$$ | nc -n -u -W 1 -w 3 -s ${${ip}${inet:S/inet//}}\
234	    ${ECO_IN${inet:S/inet//}} 7 | grep $$$$
235.else
236	echo $$$$ | nc -n -u -W 1 -w 3 ${${ip}${inet:S/inet//}} 7 | grep $$$$
237.endif
238
239# Send a data stream to TCP echo port 7 to all destination addresses
240# with netcat.  Use enough data to make sure PMTU discovery works.
241# Count the reflected bytes and compare with the transmitted ones.
242# Delete host route before test to trigger PMTU discovery.
243
244REGRESS_TARGETS +=	run-tcp-${inet}-${ip}
245run-tcp-${inet}-${ip}: stamp-pfctl
246	@echo '\n======== $@ ========'
247	@echo Check tcp ${ip}${inet:S/inet//}:
248	${SUDO} route -n delete -host -inet ${${ip}${inet:S/inet//}} || true
249.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
250	openssl rand 200000 | nc -n -N -w 10 -s ${${ip}${inet:S/inet//}}\
251	    ${ECO_IN${inet:S/inet//}} 7 | wc -c | grep '200000$$'
252.else
253	openssl rand 200000 | nc -n -N -w 10 ${${ip}${inet:S/inet//}} 7 |\
254	    wc -c | grep '200000$$'
255.endif
256
257.endfor # ip
258
259# Run traceroute with ICMP and UDP to all destination addresses.
260# Expect three hops in output and that every probe has a response.
261
262TRACEROUTE_CHECK =	awk \
263    'BEGIN{ x=0 } \
264    { print $$0 } \
265    { n=$$1 } \
266    /\*/{ x++ } \
267    END{ if (n!=3) { print "hopcount is not 3: "n; exit 1 } } \
268    END{ if (x!=0) { print "unanswered probes: "x; exit 1 } }'
269
270.for ip in ECO_IN ECO_OUT RDR_IN RDR_OUT AF_IN RTT_IN RTT_OUT RPT_IN RPT_OUT
271.for proto in icmp udp
272REGRESS_TARGETS +=	run-traceroute-${proto}-${inet}-${ip}
273run-traceroute-${proto}-${inet}-${ip}: stamp-pfctl
274	@echo '\n======== $@ ========'
275	@echo Check traceroute ${proto} ${ip${inet:S/inet//}}:
276.if "RPT_IN" == ${ip} || "RPT_OUT" == ${ip}
277	traceroute${inet:S/inet//} ${proto:S/icmp/-I/:S/udp//}\
278	    -s ${${ip}${inet:S/inet//}} ${ECO_IN${inet:S/inet//}} |\
279	    ${TRACEROUTE_CHECK}
280.else
281	traceroute${inet:S/inet//} ${proto:S/icmp/-I/:S/udp//}\
282	    ${${ip}${inet:S/inet//}} | ${TRACEROUTE_CHECK}
283.endif
284.endfor # proto
285.endfor # ip
286
287.endfor # inet
288
289CLEANFILES +=		addr.py *.pyc *.log stamp-*
290
291.PHONY: check-setup
292
293# Check wether the address, route and remote setup is correct
294check-setup: check-setup-src check-setup-pf check-setup-rt check-setup-eco
295
296check-setup-src:
297	@echo '\n======== $@ ========'
298.for ip in SRC_OUT RPT_IN RPT_OUT
299	ping -n -c 1 ${${ip}}  # ${ip}
300	route -n get -inet ${${ip}} | grep -q 'flags: .*LOCAL'  # ${ip}
301.endfor
302	ping -n -c 1 ${PF_IN}  # PF_IN
303	route -n get -inet ${PF_IN} | fgrep -q 'interface: ${SRC_IF}' \
304	    # PF_IN SRC_IF
305.for ip in PF_OUT RT_IN RT_OUT ECO_IN ECO_OUT RDR_IN RDR_OUT AF_IN\
306    RTT_IN RTT_OUT
307	route -n get -inet ${${ip}} | fgrep -q 'gateway: ${PF_IN}' \
308	    # ${ip} PF_IN
309.endfor
310.for ip in SRC_OUT RPT_IN RPT_OUT
311	ping6 -n -c 1 ${${ip}6}  # ${ip}6
312	route -n get -inet6 ${${ip}6} | grep -q 'flags: .*LOCAL'  # ${ip}6
313.endfor
314	ping6 -n -c 1 ${PF_IN6}  # PF_IN6
315	route -n get -inet6 ${PF_IN6} | fgrep -q 'interface: ${SRC_IF}' \
316	    # PF_IN6 SRC_IF
317.for ip in PF_OUT RT_IN RT_OUT ECO_IN ECO_OUT RDR_IN RDR_OUT AF_IN\
318    RTT_IN RTT_OUT
319	route -n get -inet6 ${${ip}6} | fgrep -q 'gateway: ${PF_IN6}' \
320	    # ${ip}6 PF_IN6
321.endfor
322
323check-setup-pf:
324	@echo '\n======== $@ ========'
325	ssh ${PF_SSH} ping -n -c 1 ${PF_IN}  # PF_IN
326	ssh ${PF_SSH} route -n get -inet ${PF_IN} | grep -q 'flags: .*LOCAL' \
327	    # PF_IN
328	ssh ${PF_SSH} ping -n -c 1 ${SRC_OUT}  # SRC_OUT
329	ssh ${PF_SSH} ping -n -c 1 ${PF_OUT}  # PF_OUT
330	ssh ${PF_SSH} route -n get -inet ${PF_OUT} | grep -q 'flags: .*LOCAL' \
331	    # PF_OUT
332	ssh ${PF_SSH} ping -n -c 1 ${RT_IN}  # RT_IN
333.for ip in RT_OUT ECO_IN ECO_OUT
334	ssh ${PF_SSH} route -n get -inet ${${ip}} |\
335	    fgrep -q 'gateway: ${RT_IN}'  # ${ip} RT_IN
336.endfor
337.for ip in RTT_IN RTT_OUT RPT_IN RPT_OUT
338	ssh ${PF_SSH} route -n get -inet ${${ip}} | grep -q 'flags: .*REJECT' \
339	    # ${ip} reject
340.endfor
341	ssh ${PF_SSH} ping6 -n -c 1 ${PF_IN6}  # PF_IN6
342	ssh ${PF_SSH} route -n get -inet6 ${PF_IN6} | grep -q 'flags: .*LOCAL' \
343	    # PF_IN6
344	ssh ${PF_SSH} ping6 -n -c 1 ${SRC_OUT6}  # SRC_OUT6
345	ssh ${PF_SSH} ping6 -n -c 1 ${PF_OUT6}  # PF_OUT6
346	ssh ${PF_SSH} route -n get -inet6 ${PF_OUT6} |\
347	    grep -q 'flags: .*LOCAL'  # PF_OUT6
348	ssh ${PF_SSH} ping6 -n -c 1 ${RT_IN6}  # RT_IN6
349.for ip in RT_OUT ECO_IN ECO_OUT
350	ssh ${PF_SSH} route -n get -inet6 ${${ip}6} |\
351	    fgrep -q 'gateway: ${RT_IN6}'  # ${ip}6 RT_IN6
352.endfor
353.for ip in RTT_IN RTT_OUT RPT_IN RPT_OUT
354	ssh ${PF_SSH} route -n get -inet6 ${${ip}6} |\
355	    grep -q 'flags: .*REJECT'  # ${ip}6 reject
356.endfor
357	ssh ${PF_SSH} ${SUDO} pfctl -sr | grep '^anchor "regress" all$$'
358	ssh ${PF_SSH} ${SUDO} pfctl -si | grep '^Status: Enabled '
359	ssh ${PF_SSH} sysctl net.inet.ip.forwarding | fgrep =1
360	ssh ${PF_SSH} sysctl net.inet6.ip6.forwarding | fgrep =1
361	ssh ${PF_SSH} ifconfig ${PF_IFOUT} | fgrep 'mtu 1400'
362
363check-setup-rt:
364	@echo '\n======== $@ ========'
365	ssh ${RT_SSH} ping -n -c 1 ${RT_IN}  # RT_IN
366	ssh ${RT_SSH} route -n get -inet ${RT_IN} | grep -q 'flags: .*LOCAL' \
367	    # RT_IN
368	ssh ${RT_SSH} ping -n -c 1 ${PF_OUT}  # PF_OUT
369.for ip in PF_IN SRC_OUT RPT_IN RPT_OUT
370	ssh ${RT_SSH} route -n get -inet ${${ip}} |\
371	    fgrep -q 'gateway: ${PF_OUT}'  # ${ip} PF_OUT
372.endfor
373	ssh ${RT_SSH} ping -n -c 1 ${RT_OUT}  # RT_OUT
374	ssh ${RT_SSH} route -n get -inet ${RT_OUT} | grep -q 'flags: .*LOCAL' \
375	    # RT_OUT
376	ssh ${RT_SSH} ping -n -c 1 ${ECO_IN}  # ECO_IN
377.for ip in ECO_OUT RTT_IN RTT_OUT
378	ssh ${RT_SSH} route -n get -inet ${${ip}} |\
379	    fgrep -q 'gateway: ${ECO_IN}'  # ${ip} ECO_IN
380.endfor
381	ssh ${RT_SSH} ping6 -n -c 1 ${RT_IN6}  # RT_IN6
382	ssh ${RT_SSH} route -n get -inet6 ${RT_IN6} | grep -q 'flags: .*LOCAL' \
383	    # RT_IN6
384	ssh ${RT_SSH} ping6 -n -c 1 ${PF_OUT6}  # PF_OUT6
385.for ip in PF_IN SRC_OUT RPT_IN RPT_OUT
386	ssh ${RT_SSH} route -n get -inet6 ${${ip}6} |\
387	    fgrep -q 'gateway: ${PF_OUT6}'  # ${ip}6 PF_OUT6
388.endfor
389	ssh ${RT_SSH} ping6 -n -c 1 ${RT_OUT6}  # RT_OUT6
390	ssh ${RT_SSH} route -n get -inet6 ${RT_OUT6} |\
391	    grep -q 'flags: .*LOCAL'  # RT_OUT6
392	ssh ${RT_SSH} ping6 -n -c 1 ${ECO_IN6}  # ECO_IN6
393.for ip in ECO_OUT RTT_IN RTT_OUT
394	ssh ${RT_SSH} route -n get -inet6 ${${ip}6} |\
395	    fgrep -q 'gateway: ${ECO_IN6}'  # ${ip}6 ECO_IN6
396.endfor
397	ssh ${RT_SSH} sysctl net.inet.ip.forwarding | fgrep =1
398	ssh ${RT_SSH} sysctl net.inet6.ip6.forwarding | fgrep =1
399	ssh ${RT_SSH} ifconfig | fgrep 'mtu 1300'
400
401check-setup-eco:
402	@echo '\n======== $@ ========'
403.for ip in ECO_IN ECO_OUT RTT_IN RTT_OUT
404	ssh ${ECO_SSH} ping -n -c 1 ${${ip}}  # ${ip}
405	ssh ${ECO_SSH} route -n get -inet ${${ip}} | grep -q 'flags: .*LOCAL' \
406	    # ${ip}
407.endfor
408	ssh ${ECO_SSH} ping -n -c 1 ${RT_OUT}  # RT_OUT
409.for ip in RT_IN PF_OUT PF_IN SRC_OUT RPT_IN RPT_OUT
410	ssh ${ECO_SSH} route -n get -inet ${${ip}} |\
411	    fgrep -q 'gateway: ${RT_OUT}'  # ${ip} RT_OUT
412.endfor
413.for ip in ECO_IN ECO_OUT RTT_IN RTT_OUT
414	ssh ${ECO_SSH} ping6 -n -c 1 ${${ip}6}  # ${ip}6
415	ssh ${ECO_SSH} route -n get -inet6 ${${ip}6} |\
416	    grep -q 'flags: .*LOCAL'  # ${ip}6
417.endfor
418	ssh ${ECO_SSH} ping6 -n -c 1 ${RT_OUT6}  # RT_OUT6
419.for ip in RT_IN PF_OUT PF_IN SRC_OUT RPT_IN RPT_OUT
420	ssh ${ECO_SSH} route -n get -inet6 ${${ip}6} |\
421	    fgrep -q 'gateway: ${RT_OUT6}'  # ${ip}6 RT_OUT6
422.endfor
423.for inet in inet inet6
424.for proto in udp tcp
425	ssh ${ECO_SSH} netstat -na -f ${inet} -p ${proto} | fgrep ' *.7 '
426.endfor
427.endfor
428.for ip in ECO_IN ECO_OUT RTT_IN RTT_OUT
429	ssh ${ECO_SSH} netstat -nav -f inet -p udp | fgrep ' ${${ip}}.7 '
430	ssh ${ECO_SSH} netstat -nav -f inet6 -p udp | fgrep ' ${${ip}6}.7 '
431.endfor
432
433.include <bsd.regress.mk>
434