198c5f988SKristof Provost /*- 298c5f988SKristof Provost * Copyright (c) 2018 Kristof Provost <kp@FreeBSD.org> 398c5f988SKristof Provost * 498c5f988SKristof Provost * Redistribution and use in source and binary forms, with or without 598c5f988SKristof Provost * modification, are permitted provided that the following conditions 698c5f988SKristof Provost * are met: 798c5f988SKristof Provost * 1. Redistributions of source code must retain the above copyright 898c5f988SKristof Provost * notice, this list of conditions and the following disclaimer. 998c5f988SKristof Provost * 2. Redistributions in binary form must reproduce the above copyright 1098c5f988SKristof Provost * notice, this list of conditions and the following disclaimer in the 1198c5f988SKristof Provost * documentation and/or other materials provided with the distribution. 1298c5f988SKristof Provost * 1398c5f988SKristof Provost * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1498c5f988SKristof Provost * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1598c5f988SKristof Provost * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1698c5f988SKristof Provost * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1798c5f988SKristof Provost * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1898c5f988SKristof Provost * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1998c5f988SKristof Provost * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2098c5f988SKristof Provost * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2198c5f988SKristof Provost * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2298c5f988SKristof Provost * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2398c5f988SKristof Provost * SUCH DAMAGE. 2498c5f988SKristof Provost * 2598c5f988SKristof Provost * $FreeBSD$ 2698c5f988SKristof Provost */ 2798c5f988SKristof Provost 2898c5f988SKristof Provost #include <sys/param.h> 2998c5f988SKristof Provost #include <sys/module.h> 3098c5f988SKristof Provost #include <sys/types.h> 3198c5f988SKristof Provost #include <sys/ioctl.h> 3298c5f988SKristof Provost #include <sys/socket.h> 3398c5f988SKristof Provost 3498c5f988SKristof Provost #include <net/if.h> 3598c5f988SKristof Provost #include <net/pfvar.h> 3698c5f988SKristof Provost 3798c5f988SKristof Provost #include <fcntl.h> 3898c5f988SKristof Provost #include <stdio.h> 3998c5f988SKristof Provost 4098c5f988SKristof Provost #include <atf-c.h> 4198c5f988SKristof Provost 4298c5f988SKristof Provost static int dev; 4398c5f988SKristof Provost 4498c5f988SKristof Provost #define COMMON_HEAD() \ 4598c5f988SKristof Provost if (modfind("pf") == -1) \ 4698c5f988SKristof Provost atf_tc_skip("pf not loaded"); \ 4798c5f988SKristof Provost dev = open("/dev/pf", O_RDWR); \ 4898c5f988SKristof Provost if (dev == -1) \ 4998c5f988SKristof Provost atf_tc_skip("Failed to open /dev/pf"); 5098c5f988SKristof Provost 5198c5f988SKristof Provost #define COMMON_CLEANUP() \ 5298c5f988SKristof Provost close(dev); 5398c5f988SKristof Provost 541ff545d6SKristof Provost void 551ff545d6SKristof Provost common_init_tbl(struct pfr_table *tbl) 561ff545d6SKristof Provost { 571ff545d6SKristof Provost bzero(tbl, sizeof(struct pfr_table)); 581ff545d6SKristof Provost strcpy(tbl->pfrt_anchor, "anchor"); 591ff545d6SKristof Provost strcpy(tbl->pfrt_name, "name"); 601ff545d6SKristof Provost tbl->pfrt_flags = 0; 611ff545d6SKristof Provost tbl->pfrt_fback = 0; 621ff545d6SKristof Provost } 631ff545d6SKristof Provost 6498c5f988SKristof Provost ATF_TC_WITHOUT_HEAD(addtables); 6598c5f988SKristof Provost ATF_TC_BODY(addtables, tc) 6698c5f988SKristof Provost { 6798c5f988SKristof Provost struct pfioc_table io; 6898c5f988SKristof Provost struct pfr_table tbl; 6998c5f988SKristof Provost int flags; 7098c5f988SKristof Provost 7198c5f988SKristof Provost COMMON_HEAD(); 7298c5f988SKristof Provost 7398c5f988SKristof Provost flags = 0; 7498c5f988SKristof Provost 7598c5f988SKristof Provost bzero(&io, sizeof(io)); 7698c5f988SKristof Provost io.pfrio_flags = flags; 7798c5f988SKristof Provost io.pfrio_buffer = &tbl; 7898c5f988SKristof Provost io.pfrio_esize = sizeof(tbl); 7998c5f988SKristof Provost 8098c5f988SKristof Provost /* Negative size */ 8198c5f988SKristof Provost io.pfrio_size = -1; 8298c5f988SKristof Provost if (ioctl(dev, DIOCRADDTABLES, &io) == 0) 8398c5f988SKristof Provost atf_tc_fail("Request with size -1 succeeded"); 8498c5f988SKristof Provost 8598c5f988SKristof Provost /* Overly large size */ 8698c5f988SKristof Provost io.pfrio_size = 1 << 24; 8798c5f988SKristof Provost if (ioctl(dev, DIOCRADDTABLES, &io) == 0) 8898c5f988SKristof Provost atf_tc_fail("Request with size 1 << 24 succeeded"); 8998c5f988SKristof Provost 9098c5f988SKristof Provost /* NULL buffer */ 9198c5f988SKristof Provost io.pfrio_size = 1; 9298c5f988SKristof Provost io.pfrio_buffer = NULL; 9398c5f988SKristof Provost if (ioctl(dev, DIOCRADDTABLES, &io) == 0) 9498c5f988SKristof Provost atf_tc_fail("Request with NULL buffer succeeded"); 9598c5f988SKristof Provost 9698c5f988SKristof Provost COMMON_CLEANUP(); 9798c5f988SKristof Provost } 9898c5f988SKristof Provost 9998c5f988SKristof Provost ATF_TC_WITHOUT_HEAD(deltables); 10098c5f988SKristof Provost ATF_TC_BODY(deltables, tc) 10198c5f988SKristof Provost { 10298c5f988SKristof Provost struct pfioc_table io; 10398c5f988SKristof Provost struct pfr_table tbl; 10498c5f988SKristof Provost int flags; 10598c5f988SKristof Provost 10698c5f988SKristof Provost COMMON_HEAD(); 10798c5f988SKristof Provost 10898c5f988SKristof Provost flags = 0; 10998c5f988SKristof Provost 11098c5f988SKristof Provost bzero(&io, sizeof(io)); 11198c5f988SKristof Provost io.pfrio_flags = flags; 11298c5f988SKristof Provost io.pfrio_buffer = &tbl; 11398c5f988SKristof Provost io.pfrio_esize = sizeof(tbl); 11498c5f988SKristof Provost 11598c5f988SKristof Provost /* Negative size */ 11698c5f988SKristof Provost io.pfrio_size = -1; 11798c5f988SKristof Provost if (ioctl(dev, DIOCRDELTABLES, &io) == 0) 11898c5f988SKristof Provost atf_tc_fail("Request with size -1 succeeded"); 11998c5f988SKristof Provost 12098c5f988SKristof Provost /* Overly large size */ 12198c5f988SKristof Provost io.pfrio_size = 1 << 24; 12298c5f988SKristof Provost if (ioctl(dev, DIOCRDELTABLES, &io) == 0) 12398c5f988SKristof Provost atf_tc_fail("Request with size 1 << 24 succeeded"); 12498c5f988SKristof Provost 12598c5f988SKristof Provost /* NULL buffer */ 12698c5f988SKristof Provost io.pfrio_size = 1; 12798c5f988SKristof Provost io.pfrio_buffer = NULL; 12898c5f988SKristof Provost if (ioctl(dev, DIOCRDELTABLES, &io) == 0) 12998c5f988SKristof Provost atf_tc_fail("Request with NULL buffer succeeded"); 13098c5f988SKristof Provost 13198c5f988SKristof Provost COMMON_CLEANUP(); 13298c5f988SKristof Provost } 13398c5f988SKristof Provost 1341ff545d6SKristof Provost ATF_TC_WITHOUT_HEAD(gettables); 1351ff545d6SKristof Provost ATF_TC_BODY(gettables, tc) 1361ff545d6SKristof Provost { 1371ff545d6SKristof Provost struct pfioc_table io; 1381ff545d6SKristof Provost struct pfr_table tbl; 1391ff545d6SKristof Provost int flags; 1401ff545d6SKristof Provost 1411ff545d6SKristof Provost COMMON_HEAD(); 1421ff545d6SKristof Provost 1431ff545d6SKristof Provost flags = 0; 1441ff545d6SKristof Provost 1451ff545d6SKristof Provost bzero(&io, sizeof(io)); 1461ff545d6SKristof Provost io.pfrio_flags = flags; 1471ff545d6SKristof Provost io.pfrio_buffer = &tbl; 1481ff545d6SKristof Provost io.pfrio_esize = sizeof(tbl); 1491ff545d6SKristof Provost 1501ff545d6SKristof Provost /* Negative size. This will succeed, because the kernel will not copy 1511ff545d6SKristof Provost * tables than it has. */ 1521ff545d6SKristof Provost io.pfrio_size = -1; 1531ff545d6SKristof Provost if (ioctl(dev, DIOCRGETTABLES, &io) != 0) 1541ff545d6SKristof Provost atf_tc_fail("Request with size -1 failed"); 1551ff545d6SKristof Provost 1561ff545d6SKristof Provost /* Overly large size. See above. */ 1571ff545d6SKristof Provost io.pfrio_size = 1 << 24; 1581ff545d6SKristof Provost if (ioctl(dev, DIOCRGETTABLES, &io) != 0) 1591ff545d6SKristof Provost atf_tc_fail("Request with size 1 << 24 failed"); 1601ff545d6SKristof Provost 1611ff545d6SKristof Provost COMMON_CLEANUP(); 1621ff545d6SKristof Provost } 1631ff545d6SKristof Provost 1641ff545d6SKristof Provost ATF_TC_WITHOUT_HEAD(gettstats); 1651ff545d6SKristof Provost ATF_TC_BODY(gettstats, tc) 1661ff545d6SKristof Provost { 1671ff545d6SKristof Provost struct pfioc_table io; 1681ff545d6SKristof Provost struct pfr_tstats stats; 1691ff545d6SKristof Provost int flags; 1701ff545d6SKristof Provost 1711ff545d6SKristof Provost COMMON_HEAD(); 1721ff545d6SKristof Provost 1731ff545d6SKristof Provost flags = 0; 1741ff545d6SKristof Provost 1751ff545d6SKristof Provost bzero(&io, sizeof(io)); 1761ff545d6SKristof Provost io.pfrio_flags = flags; 1771ff545d6SKristof Provost io.pfrio_buffer = &stats; 1781ff545d6SKristof Provost io.pfrio_esize = sizeof(stats); 1791ff545d6SKristof Provost 1801ff545d6SKristof Provost /* Negative size. This will succeed, because the kernel will not copy 1811ff545d6SKristof Provost * tables than it has. */ 1821ff545d6SKristof Provost io.pfrio_size = -1; 1831ff545d6SKristof Provost if (ioctl(dev, DIOCRGETTSTATS, &io) != 0) 1841ff545d6SKristof Provost atf_tc_fail("Request with size -1 failed"); 1851ff545d6SKristof Provost 1861ff545d6SKristof Provost /* Overly large size. See above. */ 1871ff545d6SKristof Provost io.pfrio_size = 1 << 24; 1881ff545d6SKristof Provost if (ioctl(dev, DIOCRGETTSTATS, &io) != 0) 1891ff545d6SKristof Provost atf_tc_fail("Request with size 1 << 24 failed"); 1901ff545d6SKristof Provost 1911ff545d6SKristof Provost COMMON_CLEANUP(); 1921ff545d6SKristof Provost } 1931ff545d6SKristof Provost 1941ff545d6SKristof Provost ATF_TC_WITHOUT_HEAD(clrtstats); 1951ff545d6SKristof Provost ATF_TC_BODY(clrtstats, tc) 1961ff545d6SKristof Provost { 1971ff545d6SKristof Provost struct pfioc_table io; 1981ff545d6SKristof Provost struct pfr_table tbl; 1991ff545d6SKristof Provost int flags; 2001ff545d6SKristof Provost 2011ff545d6SKristof Provost COMMON_HEAD(); 2021ff545d6SKristof Provost 2031ff545d6SKristof Provost flags = 0; 2041ff545d6SKristof Provost 2051ff545d6SKristof Provost common_init_tbl(&tbl); 2061ff545d6SKristof Provost 2071ff545d6SKristof Provost bzero(&io, sizeof(io)); 2081ff545d6SKristof Provost io.pfrio_flags = flags; 2091ff545d6SKristof Provost io.pfrio_buffer = &tbl; 2101ff545d6SKristof Provost io.pfrio_esize = sizeof(tbl); 2111ff545d6SKristof Provost 2121ff545d6SKristof Provost /* Negative size. This will succeed, because the kernel will not copy 2131ff545d6SKristof Provost * tables than it has. */ 2141ff545d6SKristof Provost io.pfrio_size = -1; 2151ff545d6SKristof Provost if (ioctl(dev, DIOCRCLRTSTATS, &io) != 0) 2161ff545d6SKristof Provost atf_tc_fail("Request with size -1 failed "); 2171ff545d6SKristof Provost 2181ff545d6SKristof Provost /* Overly large size. See above. */ 2191ff545d6SKristof Provost io.pfrio_size = 1 << 24; 2201ff545d6SKristof Provost if (ioctl(dev, DIOCRCLRTSTATS, &io) != 0) 2211ff545d6SKristof Provost atf_tc_fail("Request with size 1 << 24 failed"); 2221ff545d6SKristof Provost 2231ff545d6SKristof Provost COMMON_CLEANUP(); 2241ff545d6SKristof Provost } 2251ff545d6SKristof Provost 2261ff545d6SKristof Provost ATF_TC_WITHOUT_HEAD(settflags); 2271ff545d6SKristof Provost ATF_TC_BODY(settflags, tc) 2281ff545d6SKristof Provost { 2291ff545d6SKristof Provost struct pfioc_table io; 2301ff545d6SKristof Provost struct pfr_table tbl; 2311ff545d6SKristof Provost int flags; 2321ff545d6SKristof Provost 2331ff545d6SKristof Provost COMMON_HEAD(); 2341ff545d6SKristof Provost 2351ff545d6SKristof Provost flags = 0; 2361ff545d6SKristof Provost 2371ff545d6SKristof Provost common_init_tbl(&tbl); 2381ff545d6SKristof Provost 2391ff545d6SKristof Provost bzero(&io, sizeof(io)); 2401ff545d6SKristof Provost io.pfrio_flags = flags; 2411ff545d6SKristof Provost io.pfrio_buffer = &tbl; 2421ff545d6SKristof Provost io.pfrio_esize = sizeof(tbl); 2431ff545d6SKristof Provost 2441ff545d6SKristof Provost /* Negative size. This will succeed, because the kernel will not copy 2451ff545d6SKristof Provost * tables than it has. */ 2461ff545d6SKristof Provost io.pfrio_size = -1; 2471ff545d6SKristof Provost if (ioctl(dev, DIOCRSETTFLAGS, &io) != 0) 2481ff545d6SKristof Provost atf_tc_fail("Request with size -1 failed"); 2491ff545d6SKristof Provost 2501ff545d6SKristof Provost /* Overly large size. See above. */ 2511ff545d6SKristof Provost io.pfrio_size = 1 << 28; 2521ff545d6SKristof Provost if (ioctl(dev, DIOCRSETTFLAGS, &io) != 0) 2531ff545d6SKristof Provost atf_tc_fail("Request with size 1 << 24 failed"); 2541ff545d6SKristof Provost 2551ff545d6SKristof Provost COMMON_CLEANUP(); 2561ff545d6SKristof Provost } 2571ff545d6SKristof Provost 258*8e748b94SKristof Provost ATF_TC_WITHOUT_HEAD(igetifaces); 259*8e748b94SKristof Provost ATF_TC_BODY(igetifaces, tc) 260*8e748b94SKristof Provost { 261*8e748b94SKristof Provost struct pfioc_iface io; 262*8e748b94SKristof Provost struct pfi_kif kif; 263*8e748b94SKristof Provost 264*8e748b94SKristof Provost COMMON_HEAD(); 265*8e748b94SKristof Provost 266*8e748b94SKristof Provost bzero(&io, sizeof(io)); 267*8e748b94SKristof Provost io.pfiio_flags = 0; 268*8e748b94SKristof Provost io.pfiio_buffer = &kif; 269*8e748b94SKristof Provost io.pfiio_esize = sizeof(kif); 270*8e748b94SKristof Provost 271*8e748b94SKristof Provost /* Negative size */ 272*8e748b94SKristof Provost io.pfiio_size = -1; 273*8e748b94SKristof Provost if (ioctl(dev, DIOCIGETIFACES, &io) == 0) 274*8e748b94SKristof Provost atf_tc_fail("request with size -1 succeeded"); 275*8e748b94SKristof Provost 276*8e748b94SKristof Provost /* Overflow size */ 277*8e748b94SKristof Provost io.pfiio_size = 1 << 31; 278*8e748b94SKristof Provost if (ioctl(dev, DIOCIGETIFACES, &io) == 0) 279*8e748b94SKristof Provost atf_tc_fail("request with size 1 << 31 succeeded"); 280*8e748b94SKristof Provost 281*8e748b94SKristof Provost COMMON_CLEANUP(); 282*8e748b94SKristof Provost } 283*8e748b94SKristof Provost 284*8e748b94SKristof Provost ATF_TC_WITHOUT_HEAD(commit); 285*8e748b94SKristof Provost ATF_TC_BODY(commit, tc) 286*8e748b94SKristof Provost { 287*8e748b94SKristof Provost struct pfioc_trans io; 288*8e748b94SKristof Provost struct pfioc_trans_e ioe; 289*8e748b94SKristof Provost 290*8e748b94SKristof Provost COMMON_HEAD(); 291*8e748b94SKristof Provost 292*8e748b94SKristof Provost bzero(&io, sizeof(io)); 293*8e748b94SKristof Provost io.esize = sizeof(ioe); 294*8e748b94SKristof Provost io.array = &ioe; 295*8e748b94SKristof Provost 296*8e748b94SKristof Provost /* Negative size */ 297*8e748b94SKristof Provost io.size = -1; 298*8e748b94SKristof Provost if (ioctl(dev, DIOCXCOMMIT, &io) == 0) 299*8e748b94SKristof Provost atf_tc_fail("request with size -1 succeeded"); 300*8e748b94SKristof Provost 301*8e748b94SKristof Provost /* Overflow size */ 302*8e748b94SKristof Provost io.size = 1 << 30; 303*8e748b94SKristof Provost if (ioctl(dev, DIOCXCOMMIT, &io) == 0) 304*8e748b94SKristof Provost atf_tc_fail("request with size 1 << 30 succeeded"); 305*8e748b94SKristof Provost 306*8e748b94SKristof Provost /* NULL buffer */ 307*8e748b94SKristof Provost io.size = 1; 308*8e748b94SKristof Provost io.array = NULL; 309*8e748b94SKristof Provost if (ioctl(dev, DIOCXCOMMIT, &io) == 0) 310*8e748b94SKristof Provost atf_tc_fail("request with size -1 succeeded"); 311*8e748b94SKristof Provost 312*8e748b94SKristof Provost COMMON_CLEANUP(); 313*8e748b94SKristof Provost } 314*8e748b94SKristof Provost 31598c5f988SKristof Provost ATF_TP_ADD_TCS(tp) 31698c5f988SKristof Provost { 31798c5f988SKristof Provost ATF_TP_ADD_TC(tp, addtables); 31898c5f988SKristof Provost ATF_TP_ADD_TC(tp, deltables); 3191ff545d6SKristof Provost ATF_TP_ADD_TC(tp, gettables); 3201ff545d6SKristof Provost ATF_TP_ADD_TC(tp, gettstats); 3211ff545d6SKristof Provost ATF_TP_ADD_TC(tp, clrtstats); 3221ff545d6SKristof Provost ATF_TP_ADD_TC(tp, settflags); 323*8e748b94SKristof Provost ATF_TP_ADD_TC(tp, igetifaces); 324*8e748b94SKristof Provost ATF_TP_ADD_TC(tp, commit); 32598c5f988SKristof Provost 32698c5f988SKristof Provost return (atf_no_error()); 32798c5f988SKristof Provost } 328