1*70788dfdSkn# $OpenBSD: Makefile,v 1.15 2020/12/30 21:40:33 kn Exp $ 2a13597faSbluhm 3a13597faSbluhm# The following ports must be installed: 4a13597faSbluhm# 5a13597faSbluhm# scapy powerful interactive packet manipulation in python 6a13597faSbluhm 7*70788dfdSkn.if ! exists(/usr/local/bin/scapy) 8a13597faSbluhmregress: 9*70788dfdSkn @echo Install scapy package to run this regress. 1054eefd0cSbluhm @echo SKIPPED 11a13597faSbluhm.endif 12a13597faSbluhm 13a13597faSbluhm# This test needs a manual setup of two machines 14a13597faSbluhm# Set up machines: LOCAL REMOTE 15a13597faSbluhm# LOCAL is the machine where this makefile is running. 16a13597faSbluhm# REMOTE is running OpenBSD with ARP to test the Address Resolution Protocol. 17a13597faSbluhm# FAKE is an non existing machine, its IP is used in the tests. 18a13597faSbluhm# OTHER is an IP on REMOTE, but configured on another interface. 19b07894d8Sbluhm# OTHER_FAKE is an non existing IP on another interface. 20a13597faSbluhm# REMOTE_SSH is the hostname to log in on the REMOTE machine. 21a13597faSbluhm 22a13597faSbluhm# Configure Addresses on the machines. 23a13597faSbluhm# Adapt interface and addresse variables to your local setup. 24a13597faSbluhm# 25a13597faSbluhmLOCAL_IF ?= 26a13597faSbluhmLOCAL_MAC ?= 27a13597faSbluhmREMOTE_MAC ?= 28a13597faSbluhmFAKE_MAC ?= 12:34:56:78:9a:bc 293c9f2cb4SmpiPROXY_MAC ?= 00:90:27:bb:cc:dd 30a13597faSbluhmREMOTE_SSH ?= 31a13597faSbluhm 32a13597faSbluhmLOCAL_ADDR ?= 10.188.70.17 33a13597faSbluhmREMOTE_ADDR ?= 10.188.70.70 34a13597faSbluhmFAKE_ADDR ?= 10.188.70.188 35a13597faSbluhmOTHER_ADDR ?= 10.188.211.70 36b07894d8SbluhmOTHER_FAKE_ADDR ?= 10.188.211.188 37a13597faSbluhm 38a13597faSbluhm.if empty (LOCAL_IF) || empty (LOCAL_MAC) || empty (REMOTE_MAC) || \ 39a13597faSbluhm empty (FAKE_MAC) || empty (REMOTE_SSH) || empty (LOCAL_ADDR) || \ 40a13597faSbluhm empty (REMOTE_ADDR) || empty (FAKE_ADDR) || empty (OTHER_ADDR) || \ 41b07894d8Sbluhm empty (OTHER_FAKE_ADDR) 42a13597faSbluhmregress: 43a13597faSbluhm @echo this tests needs a remote machine to operate on 44a13597faSbluhm @echo LOCAL_IF LOCAL_MAC REMOTE_MAC FAKE_MAC REMOTE_SSH LOCAL_ADDR 45b07894d8Sbluhm @echo REMOTE_ADDR FAKE_ADDR OTHER_ADDR OTHER_FAKE_ADDR are empty 46a13597faSbluhm @echo fill out these variables for additional tests 4754eefd0cSbluhm @echo SKIPPED 48a13597faSbluhm.endif 49a13597faSbluhm 50510ab291Sbluhm.if ! empty (REMOTE_SSH) 51510ab291Sbluhm.if make (regress) || make (all) 52f39ab060Sbluhm.BEGIN: 53510ab291Sbluhm ${SUDO} true 54510ab291Sbluhm ssh -t ${REMOTE_SSH} ${SUDO} true 55ac29c8e0Sbluhm @echo 56510ab291Sbluhm.endif 57510ab291Sbluhm.endif 58510ab291Sbluhm 59a13597faSbluhm# Create python include file containing the addresses. 60a13597faSbluhmaddr.py: Makefile 61a13597faSbluhm rm -f $@ $@.tmp 62a13597faSbluhm echo 'LOCAL_IF = "${LOCAL_IF}"' >>$@.tmp 63a13597faSbluhm.for var in LOCAL REMOTE FAKE 64a13597faSbluhm echo '${var}_MAC = "${${var}_MAC}"' >>$@.tmp 65a13597faSbluhm.endfor 66b07894d8Sbluhm.for var in LOCAL REMOTE FAKE OTHER OTHER_FAKE 67a13597faSbluhm echo '${var}_ADDR = "${${var}_ADDR}"' >>$@.tmp 68a13597faSbluhm.endfor 69a13597faSbluhm mv $@.tmp $@ 70a13597faSbluhm 71a13597faSbluhm# Set variables so that make runs with and without obj directory. 72a13597faSbluhm# Only do that if necessary to keep visible output short. 73a13597faSbluhm.if ${.CURDIR} == ${.OBJDIR} 74ac29c8e0SbluhmPYTHON = python3 -u ./ 75a13597faSbluhm.else 76ac29c8e0SbluhmPYTHON = PYTHONPATH=${.OBJDIR} python3 -u ${.CURDIR}/ 77a13597faSbluhm.endif 78a13597faSbluhm 796f429951Sbluhm# Clear local and remote ARP cache. 80f39ab060SbluhmREGRESS_SETUP += clean-arp 81f39ab060SbluhmREGRESS_CLEANUP += clean-arp 826f429951Sbluhmclean-arp: 836f429951Sbluhm ${SUDO} arp -da 84510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -da 856f429951Sbluhm 86018ce5eeSbluhm# Clear ARP cache and ping all addresses. This ensures that 87018ce5eeSbluhm# the IP addresses are configured and all routing table are set up 88a13597faSbluhm# to allow bidirectional packet flow. 89f39ab060SbluhmREGRESS_TARGETS += run-ping 90f39ab060Sbluhmrun-ping: 91a13597faSbluhm.for ip in LOCAL_ADDR REMOTE_ADDR 92a13597faSbluhm @echo Check ping ${ip} 93a13597faSbluhm ping -n -c 1 ${${ip}} 94a13597faSbluhm.endfor 95a13597faSbluhm 96018ce5eeSbluhm# Send an ARP request from the local machine, asking for the remote 97018ce5eeSbluhm# machine's MAC. Target MAC is broadcast, Target IP is remote address. 98018ce5eeSbluhm# Check that all fields of the answer are filled out correctly. 99018ce5eeSbluhm# Check that the remote machine has the local IP and MAC in its ARP table. 100f39ab060SbluhmREGRESS_TARGETS += run-arp-request 101f39ab060Sbluhmrun-arp-request: addr.py 102a13597faSbluhm @echo Send ARP Request for remote address and insert local address 103a13597faSbluhm ${SUDO} ${PYTHON}arp_request.py 104525d747aSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 105a13597faSbluhm grep '^${LOCAL_ADDR} .* ${LOCAL_MAC} ' arp.log 106a13597faSbluhm 107018ce5eeSbluhm# Send an ARP request from the local machine, but use a multicast MAC 108018ce5eeSbluhm# as sender. Although there is a special check in in_arpinput(), 109018ce5eeSbluhm# this must be answered. The ARP entry on the remote machine for the 110018ce5eeSbluhm# local address is changed to the multicast MAC. 111018ce5eeSbluhm# Check that all fields of the answer are filled out correctly. 112018ce5eeSbluhm# Check that the remote machine overwrites the local address. 113f39ab060SbluhmREGRESS_TARGETS += run-arp-multicast 114f39ab060Sbluhmrun-arp-multicast: addr.py 115a13597faSbluhm @echo Send ARP Request and overwrite entry with multicast ethernet 116510ab291Sbluhm ssh ${REMOTE_SSH} logger -t "arp-regress[$$$$]" $@ 117510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -s ${LOCAL_ADDR} ${LOCAL_MAC} temp 118a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages old.log 119a13597faSbluhm ${SUDO} ${PYTHON}arp_multicast.py 120a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages new.log 121525d747aSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 122510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -d ${LOCAL_ADDR} 123a13597faSbluhm diff old.log new.log | grep '^> ' >diff.log 124a13597faSbluhm grep 'bsd: arp info overwritten for ${LOCAL_ADDR} by 33:33:33:33:33:33' diff.log 1253ce2d046Smpi grep '^${LOCAL_ADDR} .* 33:33:33:33:33:33 ' arp.log 126a13597faSbluhm 127018ce5eeSbluhm# Send an ARP probe from the local machine with the remote IP as 128018ce5eeSbluhm# target. Sender MAC is local and IP is 0. The remote machine must 129018ce5eeSbluhm# defend its IP address with an ARP reply. 130018ce5eeSbluhm# Check that all fields of the answer are filled out correctly. 131f39ab060SbluhmREGRESS_TARGETS += run-arp-probe 132f39ab060Sbluhmrun-arp-probe: addr.py 133a13597faSbluhm @echo Send ARP Probe for existing address and expect correct reply 134a13597faSbluhm ${SUDO} ${PYTHON}arp_probe.py 135a13597faSbluhm 136018ce5eeSbluhm# Send ARP request with broadcast MAC as sender. 137018ce5eeSbluhm# Check that no answer is received. 138018ce5eeSbluhm# Check that the remote machine rejects the broadcast sender. 139f39ab060SbluhmREGRESS_TARGETS += run-arp-broadcast 140f39ab060Sbluhmrun-arp-broadcast: addr.py 141a13597faSbluhm @echo Send ARP Request with broadcast as sender hardware address 142510ab291Sbluhm ssh ${REMOTE_SSH} logger -t "arp-regress[$$$$]" $@ 143a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages old.log 144a13597faSbluhm ${SUDO} ${PYTHON}arp_broadcast.py 145a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages new.log 146a13597faSbluhm diff old.log new.log | grep '^> ' >diff.log 147a13597faSbluhm grep 'bsd: arp: ether address is broadcast for IP address ${LOCAL_ADDR}' diff.log 148a13597faSbluhm 149018ce5eeSbluhm# The local machine announces that it has taken the remote machine's 150018ce5eeSbluhm# IP. The sender is the local machines MAC and the remote IP. The 151018ce5eeSbluhm# remote machine must defend its IP address with an ARP reply. 152018ce5eeSbluhm# Check that all fields of the answer are filled out correctly. 153018ce5eeSbluhm# Check that the remote machine reports an duplicate address. 154018ce5eeSbluhm# Check that the remote machine keeps its local ARP entry. 155f39ab060SbluhmREGRESS_TARGETS += run-arp-announcement 156f39ab060Sbluhmrun-arp-announcement: addr.py 157a13597faSbluhm @echo Send ARP Announcement for existing address 158510ab291Sbluhm ssh ${REMOTE_SSH} logger -t "arp-regress[$$$$]" $@ 159a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages old.log 160a13597faSbluhm ${SUDO} ${PYTHON}arp_announcement.py 161a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages new.log 162525d747aSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 163a13597faSbluhm diff old.log new.log | grep '^> ' >diff.log 164a13597faSbluhm grep 'bsd: duplicate IP address ${REMOTE_ADDR} sent from ethernet address ${LOCAL_MAC}' diff.log 165525d747aSbluhm grep '^${REMOTE_ADDR} .* ${REMOTE_MAC} .* permanent * l$$' arp.log 166a13597faSbluhm 167018ce5eeSbluhm# The local machine sends an gratuitous ARP reply for the remote IP 168018ce5eeSbluhm# with its local MAC. 169018ce5eeSbluhm# Check that no answer is received. 170018ce5eeSbluhm# Check that the remote machine reports an duplicate address. 171018ce5eeSbluhm# Check that the remote machine keeps its local ARP entry. 172f39ab060SbluhmREGRESS_TARGETS += run-arp-gratuitous 173f39ab060Sbluhmrun-arp-gratuitous: addr.py 174a13597faSbluhm @echo Send Gratuitous ARP for existing address 175510ab291Sbluhm ssh ${REMOTE_SSH} logger -t "arp-regress[$$$$]" $@ 176a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages old.log 177a13597faSbluhm ${SUDO} ${PYTHON}arp_gratuitous.py 178a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages new.log 179525d747aSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 180a13597faSbluhm diff old.log new.log | grep '^> ' >diff.log 181a13597faSbluhm grep 'bsd: duplicate IP address ${REMOTE_ADDR} sent from ethernet address ${LOCAL_MAC}' diff.log 182525d747aSbluhm grep '^${REMOTE_ADDR} .* ${REMOTE_MAC} .* permanent * l$$' arp.log 183a13597faSbluhm 184018ce5eeSbluhm# Add a permanent entry on the remote machine for a fake MAC and IP. 185018ce5eeSbluhm# Send a request form the local machine, indicating with the local 186018ce5eeSbluhm# MAC and the fake IP as sender that it claims the fake address. 187018ce5eeSbluhm# Check that no answer is received. 188018ce5eeSbluhm# Check that the attempt to overwrite the permanent entry is logged. 189018ce5eeSbluhm# Check that the remote machine keeps its permanent ARP entry. 190f39ab060SbluhmREGRESS_TARGETS += run-arp-permanent 191f39ab060Sbluhmrun-arp-permanent: addr.py 192a13597faSbluhm @echo Send ARP Request to change permanent fake address 193510ab291Sbluhm ssh ${REMOTE_SSH} logger -t "arp-regress[$$$$]" $@ 194510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -s ${FAKE_ADDR} ${FAKE_MAC} permanent 195a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages old.log 196a13597faSbluhm ${SUDO} ${PYTHON}arp_fake.py 197a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages new.log 198525d747aSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 199510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -d ${FAKE_ADDR} 200a13597faSbluhm diff old.log new.log | grep '^> ' >diff.log 201a13597faSbluhm grep 'bsd: arp: attempt to overwrite permanent entry for ${FAKE_ADDR} by ${LOCAL_MAC}' diff.log 202525d747aSbluhm grep '^${FAKE_ADDR} .* ${FAKE_MAC} .* permanent * $$' arp.log 203a13597faSbluhm 204018ce5eeSbluhm# The remote machine has a second address on another interface. 205018ce5eeSbluhm# The local machine claims this address in its sender IP. 206018ce5eeSbluhm# Check that no answer is received. 207018ce5eeSbluhm# Check that the attempt to overwrite the permanent entry is logged. 208018ce5eeSbluhm# Check that the remote machine keeps its local ARP entry. 209f39ab060SbluhmREGRESS_TARGETS += run-arp-address 210f39ab060Sbluhmrun-arp-address: addr.py 211a13597faSbluhm @echo Send ARP Request to change address on other interface 212510ab291Sbluhm ssh ${REMOTE_SSH} logger -t "arp-regress[$$$$]" $@ 213a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages old.log 214a13597faSbluhm ${SUDO} ${PYTHON}arp_other.py 215a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages new.log 216525d747aSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 217a13597faSbluhm diff old.log new.log | grep '^> ' >diff.log 218a13597faSbluhm grep 'bsd: arp: attempt to overwrite permanent entry for ${OTHER_ADDR} by ${LOCAL_MAC}' diff.log 219525d747aSbluhm grep '^${OTHER_ADDR} .* permanent * l$$' arp.log 220a13597faSbluhm 221018ce5eeSbluhm# The remote machine has a second address on another interface. Add 222018ce5eeSbluhm# a temporary ARP entry for a fake address in this network on the 223018ce5eeSbluhm# remote machine. The local machine tries to overwrite this address 224018ce5eeSbluhm# with its own MAC. 225018ce5eeSbluhm# Check that no answer is received. 226018ce5eeSbluhm# Check that the attempt to overwrite the permanent entry is logged. 227018ce5eeSbluhm# Check that the remote machine keeps its ARP entry. 228f39ab060SbluhmREGRESS_TARGETS += run-arp-temporary 229f39ab060Sbluhmrun-arp-temporary: addr.py 230a13597faSbluhm @echo Send ARP Request to change temporary entry on other interface 231510ab291Sbluhm ssh ${REMOTE_SSH} logger -t "arp-regress[$$$$]" $@ 232b07894d8Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -s ${OTHER_FAKE_ADDR} ${FAKE_MAC} temp 233a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages old.log 234a13597faSbluhm ${SUDO} ${PYTHON}arp_otherfake.py 235a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages new.log 236525d747aSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 237b07894d8Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -d ${OTHER_FAKE_ADDR} 238a13597faSbluhm diff old.log new.log | grep '^> ' >diff.log 239b07894d8Sbluhm grep 'bsd: arp: attempt to overwrite entry for ${OTHER_FAKE_ADDR} on .* by ${LOCAL_MAC} on .*' diff.log 240b07894d8Sbluhm grep '^${OTHER_FAKE_ADDR} .* ${FAKE_MAC} ' arp.log 241a13597faSbluhm 242018ce5eeSbluhm# The remote machine has a second address on another interface. Create 243018ce5eeSbluhm# an incomplete ARP entry for a fake address in this network on the 244018ce5eeSbluhm# remote machine with an unsuccessful ping. The local machine tries 245018ce5eeSbluhm# to overwrite this address with its own MAC. 246018ce5eeSbluhm# Check that no answer is received. 247018ce5eeSbluhm# Check that the attempt to add an entry is logged. 248018ce5eeSbluhm# Check that the remote machine keeps its incomplete ARP entry. 249f39ab060SbluhmREGRESS_TARGETS += run-arp-incomplete 250f39ab060Sbluhmrun-arp-incomplete: addr.py 251a13597faSbluhm @echo Send ARP Request filling an incomplete entry on other interface 252510ab291Sbluhm ssh ${REMOTE_SSH} logger -t "arp-regress[$$$$]" $@ 253b07894d8Sbluhm ssh ${REMOTE_SSH} ${SUDO} ping -n -w 1 -c 1 ${OTHER_FAKE_ADDR} || true 254a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages old.log 255a13597faSbluhm ${SUDO} ${PYTHON}arp_otherfake.py 256a13597faSbluhm scp ${REMOTE_SSH}:/var/log/messages new.log 257525d747aSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 258b07894d8Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -d ${OTHER_FAKE_ADDR} 259a13597faSbluhm diff old.log new.log | grep '^> ' >diff.log 260b07894d8Sbluhm grep 'bsd: arp: attempt to add entry for ${OTHER_FAKE_ADDR} on .* by ${LOCAL_MAC} on .*' diff.log 261b07894d8Sbluhm grep '^${OTHER_FAKE_ADDR} .* (incomplete) ' arp.log 262a13597faSbluhm 263018ce5eeSbluhm# Publish a proxy ARP entry on the remote machine for a fake address. 264018ce5eeSbluhm# The local machine requests this IP as a the target. 265018ce5eeSbluhm# Check that all fields of the answer are filled out correctly. 266018ce5eeSbluhm# Check that the remote machine has a public ARP entry. 267f39ab060SbluhmREGRESS_TARGETS += run-arp-proxy 268f39ab060Sbluhmrun-arp-proxy: addr.py 269a13597faSbluhm @echo Send ARP Request for fake address that is proxied 270510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -s ${FAKE_ADDR} ${PROXY_MAC} 271510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -s ${FAKE_ADDR} ${FAKE_MAC} pub 272a13597faSbluhm ${SUDO} ${PYTHON}arp_proxy.py 273525d747aSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 274510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -d ${FAKE_ADDR} 275510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -d ${FAKE_ADDR} 276525d747aSbluhm grep '^${FAKE_ADDR} .* ${FAKE_MAC} .* static * p$$' arp.log 277525d747aSbluhm 278018ce5eeSbluhm# Enter a static ARP entry on the remote machine for a fake address, 279018ce5eeSbluhm# but do not publish it. The local machine requests this IP as a the 280018ce5eeSbluhm# target. 281018ce5eeSbluhm# Check that no answer is received. 282018ce5eeSbluhm# Check that the remote machine has a static ARP entry. 283f39ab060SbluhmREGRESS_TARGETS += run-arp-nonproxy 284f39ab060Sbluhmrun-arp-nonproxy: addr.py 285525d747aSbluhm @echo Send ARP Request for fake address that is not published 286510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -s ${FAKE_ADDR} ${FAKE_MAC} 287525d747aSbluhm ${SUDO} ${PYTHON}arp_nonproxy.py 288525d747aSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 289510ab291Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -d ${FAKE_ADDR} 290525d747aSbluhm grep '^${FAKE_ADDR} .* ${FAKE_MAC} .* static * $$' arp.log 291a13597faSbluhm 292018ce5eeSbluhm# Publish a proxy ARP entry on the remote machine for a fake address 293018ce5eeSbluhm# on another interface. The local machine requests this IP. As the 294018ce5eeSbluhm# proxy entry is for another interface, it must not be answered. 295018ce5eeSbluhm# Check that no answer is received. 296018ce5eeSbluhm# Check that the remote machine has a public ARP entry. 297f39ab060SbluhmREGRESS_TARGETS += run-arp-otherproxy 298f39ab060Sbluhmrun-arp-otherproxy: addr.py 299018ce5eeSbluhm @echo Send ARP Request for address proxied on another interface 300b07894d8Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -s ${OTHER_FAKE_ADDR} ${FAKE_MAC} pub 301018ce5eeSbluhm ${SUDO} ${PYTHON}arp_otherproxy.py 302018ce5eeSbluhm ssh ${REMOTE_SSH} ${SUDO} arp -an >arp.log 303b07894d8Sbluhm ssh ${REMOTE_SSH} ${SUDO} arp -d ${OTHER_FAKE_ADDR} 304b07894d8Sbluhm grep '^${OTHER_FAKE_ADDR} .* ${FAKE_MAC} .* static * p$$' arp.log 305018ce5eeSbluhm 306a13597faSbluhmCLEANFILES += addr.py *.pyc *.log 307a13597faSbluhm 308a13597faSbluhm.include <bsd.regress.mk> 309