Author: kp
Date: Fri Oct  6 20:51:32 2017
New Revision: 324376
URL: https://svnweb.freebsd.org/changeset/base/324376

Log:
  pf: Very basic forwarding test
  
  This test illustrates the use of scapy to test pf.
  
  Differential Revision:        https://reviews.freebsd.org/D12581

Added:
  head/tests/sys/netpfil/pf/forward.sh   (contents, props changed)
  head/tests/sys/netpfil/pf/pft_ping.py   (contents, props changed)
Modified:
  head/tests/sys/netpfil/pf/Makefile
  head/tests/sys/netpfil/pf/utils.subr

Modified: head/tests/sys/netpfil/pf/Makefile
==============================================================================
--- head/tests/sys/netpfil/pf/Makefile  Fri Oct  6 20:43:14 2017        
(r324375)
+++ head/tests/sys/netpfil/pf/Makefile  Fri Oct  6 20:51:32 2017        
(r324376)
@@ -4,8 +4,12 @@ PACKAGE=       tests
 
 TESTSDIR=       ${TESTSBASE}/sys/netpfil/pf
 
-ATF_TESTS_SH+= pass_block
+ATF_TESTS_SH+= pass_block \
+               forward
 
-${PACKAGE}FILES+=      utils.subr
+${PACKAGE}FILES+=      utils.subr \
+                       pft_ping.py
+
+${PACKAGE}FILESMODE_pft_ping.py=       0555
 
 .include <bsd.test.mk>

Added: head/tests/sys/netpfil/pf/forward.sh
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tests/sys/netpfil/pf/forward.sh        Fri Oct  6 20:51:32 2017        
(r324376)
@@ -0,0 +1,67 @@
+# $FreeBSD$
+
+. $(atf_get_srcdir)/utils.subr
+
+atf_test_case "v4" "cleanup"
+v4_head()
+{
+       atf_set descr 'Basic forwarding test'
+       atf_set require.user root
+
+       # We need scapy to be installed for out test scripts to work
+       atf_set require.progs scapy
+}
+
+v4_body()
+{
+       pft_init
+
+       epair_send=$(pft_mkepair)
+       ifconfig ${epair_send}a 192.0.2.1/24 up
+
+       epair_recv=$(pft_mkepair)
+       ifconfig ${epair_recv}a up
+
+       pft_mkjail alcatraz ${epair_send}b ${epair_recv}b
+       jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up
+       jexec alcatraz ifconfig ${epair_recv}b 198.51.100.2/24 up
+       jexec alcatraz sysctl net.inet.ip.forwarding=1
+       jexec alcatraz arp -s 198.51.100.3 00:01:02:03:04:05
+       route add -net 198.51.100.0/24 192.0.2.2
+
+       # Sanity check, can we forward ICMP echo requests without pf?
+       atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \
+               --sendif ${epair_send}a \
+               --to 198.51.100.3 \
+               --recvif ${epair_recv}a
+
+       # Forward with pf enabled
+       printf "block in\n" | jexec alcatraz pfctl -ef -
+       atf_check -s exit:1 $(atf_get_srcdir)/pft_ping.py \
+               --sendif ${epair_send}a \
+               --to 198.51.100.3 \
+               --recvif ${epair_recv}a
+
+       printf "block out\n" | jexec alcatraz pfctl -f -
+       atf_check -s exit:1 $(atf_get_srcdir)/pft_ping.py \
+               --sendif ${epair_send}a \
+               --to 198.51.100.3 \
+               --recv ${epair_recv}a
+
+       # Allow ICMP
+       printf "block in\npass in proto icmp\n" | jexec alcatraz pfctl -f -
+       atf_check -s exit:0 $(atf_get_srcdir)/pft_ping.py \
+               --sendif ${epair_send}a \
+               --to 198.51.100.3 \
+               --recvif ${epair_recv}a
+}
+
+v4_cleanup()
+{
+       pft_cleanup
+}
+
+atf_init_test_cases()
+{
+       atf_add_test_case "v4"
+}

Added: head/tests/sys/netpfil/pf/pft_ping.py
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tests/sys/netpfil/pf/pft_ping.py       Fri Oct  6 20:51:32 2017        
(r324376)
@@ -0,0 +1,83 @@
+#!/usr/local/bin/python2.7
+
+import argparse
+import scapy.all as sp
+import sys
+import threading
+
+PAYLOAD_MAGIC = 0x42c0ffee
+
+class Sniffer(threading.Thread):
+       def __init__(self, recvif):
+               threading.Thread.__init__(self)
+
+               self._recvif = recvif
+
+               self.start()
+
+       def run(self):
+               self.packets = sp.sniff(iface=self._recvif, timeout=3)
+
+def check_ping_request(packet, dst_ip):
+       """
+       Verify that the packet matches what we'd have sent
+       """
+       ip = packet.getlayer(sp.IP)
+       if not ip:
+               return False
+       if ip.dst != dst_ip:
+               return False
+
+       icmp = packet.getlayer(sp.ICMP)
+       if not icmp:
+               return False
+       if sp.icmptypes[icmp.type] != 'echo-request':
+               return False
+
+       raw = packet.getlayer(sp.Raw)
+       if not raw:
+               return False
+       if raw.load != str(PAYLOAD_MAGIC):
+               return False
+
+       return True
+
+def ping(send_if, dst_ip):
+       req = sp.Ether() \
+               / sp.IP(dst=dst_ip) \
+               / sp.ICMP(type='echo-request') \
+               / sp.Raw(PAYLOAD_MAGIC)
+       sp.sendp(req, iface=send_if, verbose=False)
+
+def main():
+       parser = argparse.ArgumentParser("pft_ping.py",
+               description="Ping test tool")
+       parser.add_argument('--sendif', nargs=1,
+               required=True,
+               help='The interface through which the packet(s) will be sent')
+       parser.add_argument('--recvif', nargs=1,
+               help='The interface on which to expect the ICMP echo response')
+       parser.add_argument('--to', nargs=1,
+               required=True,
+               help='The destination IP address for the ICMP echo request')
+
+       args = parser.parse_args()
+
+       sniffer = None
+       if not args.recvif is None:
+               sniffer = Sniffer(args.recvif[0])
+
+       ping(args.sendif[0], args.to[0])
+
+       if sniffer:
+               sniffer.join()
+
+               for packet in sniffer.packets:
+                       if check_ping_request(packet, args.to[0]):
+                               sys.exit(0)
+
+               # We did not get the packet we expected
+               sys.exit(1)
+
+if __name__ == '__main__':
+       main()

Modified: head/tests/sys/netpfil/pf/utils.subr
==============================================================================
--- head/tests/sys/netpfil/pf/utils.subr        Fri Oct  6 20:43:14 2017        
(r324375)
+++ head/tests/sys/netpfil/pf/utils.subr        Fri Oct  6 20:51:32 2017        
(r324376)
@@ -23,8 +23,14 @@ pft_mkepair()
 pft_mkjail()
 {
        jailname=$1
-       ifname=$2
-       jail -c name=${jailname} persist vnet vnet.interface=${ifname}
+       shift
+
+       vnet_interfaces=
+       for ifname in $@
+       do
+               vnet_interfaces="${vnet_interfaces} vnet.interface=${ifname}"
+       done
+       jail -c name=${jailname} persist vnet ${vnet_interfaces}
 
        echo $jailname >> created_jails.lst
 }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to