1145522Sdarrenr/* $FreeBSD$ */ 2145522Sdarrenr 354221Sguido/* 4255332Scy * Copyright (C) 2012 by Darren Reed. 554221Sguido * 654221Sguido * $FreeBSD$ 7145522Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 854221Sguido */ 954221Sguido 1060857Sdarrenr 1154221Sguido#include <sys/param.h> 1254221Sguido#include <sys/systm.h> 1354221Sguido#include <sys/kernel.h> 1454221Sguido#include <sys/module.h> 1554221Sguido#include <sys/conf.h> 1654221Sguido#include <sys/socket.h> 1754221Sguido#include <sys/sysctl.h> 18161356Sguido#include <sys/select.h> 19161356Sguido#if __FreeBSD_version >= 500000 20161356Sguido# include <sys/selinfo.h> 21255332Scy#endif 2254221Sguido#include <net/if.h> 2354221Sguido#include <netinet/in_systm.h> 2454221Sguido#include <netinet/in.h> 2554221Sguido 2654221Sguido 27255332Scy#include "netinet/ipl.h" 28255332Scy#include "netinet/ip_compat.h" 29255332Scy#include "netinet/ip_fil.h" 30255332Scy#include "netinet/ip_state.h" 31255332Scy#include "netinet/ip_nat.h" 32255332Scy#include "netinet/ip_auth.h" 33255332Scy#include "netinet/ip_frag.h" 34255332Scy#include "netinet/ip_sync.h" 3554221Sguido 36255332Scyextern ipf_main_softc_t ipfmain; 37255332Scy 38145522Sdarrenr#if __FreeBSD_version >= 502116 39145522Sdarrenrstatic struct cdev *ipf_devs[IPL_LOGSIZE]; 40145522Sdarrenr#else 41145522Sdarrenrstatic dev_t ipf_devs[IPL_LOGSIZE]; 42145522Sdarrenr#endif 4354221Sguido 44145522Sdarrenrstatic int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ); 45145522Sdarrenrstatic int ipf_modload(void); 46145522Sdarrenrstatic int ipf_modunload(void); 47145522Sdarrenr 48255332Scy#if (__FreeBSD_version >= 500024) 49255332Scy# if (__FreeBSD_version >= 502116) 50255332Scystatic int ipfopen __P((struct cdev*, int, int, struct thread *)); 51255332Scystatic int ipfclose __P((struct cdev*, int, int, struct thread *)); 52255332Scy# else 53255332Scystatic int ipfopen __P((dev_t, int, int, struct thread *)); 54255332Scystatic int ipfclose __P((dev_t, int, int, struct thread *)); 55255332Scy# endif /* __FreeBSD_version >= 502116 */ 56255332Scy#else 57255332Scystatic int ipfopen __P((dev_t, int, int, struct proc *)); 58255332Scystatic int ipfclose __P((dev_t, int, int, struct proc *)); 59255332Scy#endif 60255332Scy#if (__FreeBSD_version >= 502116) 61255332Scystatic int ipfread __P((struct cdev*, struct uio *, int)); 62255332Scystatic int ipfwrite __P((struct cdev*, struct uio *, int)); 63255332Scy#else 64255332Scystatic int ipfread __P((dev_t, struct uio *, int)); 65255332Scystatic int ipfwrite __P((dev_t, struct uio *, int)); 66255332Scy#endif /* __FreeBSD_version >= 502116 */ 67255332Scy 68255332Scy 6954221SguidoSYSCTL_DECL(_net_inet); 70145522Sdarrenr#define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \ 71145522Sdarrenr SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \ 72145522Sdarrenr ptr, val, sysctl_ipf_int, "I", descr); 73145522Sdarrenr#define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ 74145522Sdarrenr#define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) 7554221SguidoSYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF"); 76255756ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &ipfmain.ipf_flags, 0, ""); 77255756ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &ipfmain.ipf_pass, 0, ""); 78255756ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &ipfmain.ipf_active, 0, ""); 79145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, 80255756Scy &ipfmain.ipf_tcpidletimeout, 0, ""); 81145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, 82255756Scy &ipfmain.ipf_tcphalfclosed, 0, ""); 83145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, 84255756Scy &ipfmain.ipf_tcpclosewait, 0, ""); 85145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO, 86255756Scy &ipfmain.ipf_tcplastack, 0, ""); 87145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, 88255756Scy &ipfmain.ipf_tcptimeout, 0, ""); 89145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, 90255756Scy &ipfmain.ipf_tcpclosed, 0, ""); 91145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, 92255756Scy &ipfmain.ipf_udptimeout, 0, ""); 93145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO, 94255756Scy &ipfmain.ipf_udpacktimeout, 0, ""); 95145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, 96255756Scy &ipfmain.ipf_icmptimeout, 0, ""); 97255756Scy#if 0 98255756Scy/* this needs to be resolved at compile time */ 99145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO, 100255756Scy &((ipf_nat_softc_t *)ipfmain.ipf_nat_soft)->ipf_nat_defage, 0, ""); 101145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, 102255332Scy &ipf_ipfrttl, 0, ""); 103255756Scy#endif 104255332ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_running, CTLFLAG_RD, 105255756Scy &ipfmain.ipf_running, 0, ""); 106255756Scy#if 0 107145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO, 108255756Scy &ipfmain.ipf_state_soft)->ipf_state_size, 0, ""); 109145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO, 110255756Scy &(ipfmain.ipf_state_soft)->ipf_state_max, 0, ""); 111145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_nattable_sz, CTLFLAG_RWO, 112255756Scy &(ipfmain.ipf_nat_soft)->ipf_nat_table_sz, 0, ""); 113145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_natrules_sz, CTLFLAG_RWO, 114255756Scy &(ipfmain.ipf_nat_soft)->ipf_nat_maprules_sz, 0, ""); 115145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_rdrrules_sz, CTLFLAG_RWO, 116255756Scy &(ipfmain.ipf_nat_soft)->ipf_nat_rdrrules_sz, 0, ""); 117145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_hostmap_sz, CTLFLAG_RWO, 118255756Scy &(ipfmain.ipf_nat_soft)->ipf_nat_hostmap_sz, 0, ""); 119145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO, 120255332Scy &ipf_auth_size, 0, ""); 121145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, 122255332Scy &ipf_auth_used, 0, ""); 123145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, 124255332Scy &ipf_auth_defaultage, 0, ""); 125255332Scy#endif 126255756ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &ipfmain.ipf_chksrc, 0, ""); 127255756ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &ipfmain.ipf_minttl, 0, ""); 12854221Sguido 129145522Sdarrenr#define CDEV_MAJOR 79 130170268Sdarrenr#include <sys/poll.h> 131170268Sdarrenr#if __FreeBSD_version >= 500043 132161356Sguido# include <sys/select.h> 133255332Scystatic int ipfpoll(struct cdev *dev, int events, struct thread *td); 134161356Sguido 135255332Scystatic struct cdevsw ipf_cdevsw = { 136255332Scy#if __FreeBSD_version >= 502103 137126080Sphk .d_version = D_VERSION, 138145522Sdarrenr .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */ 139255332Scy#endif 140255332Scy .d_open = ipfopen, 141255332Scy .d_close = ipfclose, 142255332Scy .d_read = ipfread, 143255332Scy .d_write = ipfwrite, 144255332Scy .d_ioctl = ipfioctl, 145255332Scy .d_poll = ipfpoll, 146255332Scy .d_name = "ipf", 147255332Scy#if __FreeBSD_version < 600000 148145522Sdarrenr .d_maj = CDEV_MAJOR, 149255332Scy#endif 15054221Sguido}; 151145522Sdarrenr#else 152255332Scystatic int ipfpoll(dev_t dev, int events, struct proc *td); 153170268Sdarrenr 154255332Scystatic struct cdevsw ipf_cdevsw = { 155255332Scy /* open */ ipfopen, 156255332Scy /* close */ ipfclose, 157255332Scy /* read */ ipfread, 158255332Scy /* write */ ipfwrite, 159255332Scy /* ioctl */ ipfioctl, 160255332Scy /* poll */ ipfpoll, 161145522Sdarrenr /* mmap */ nommap, 162145522Sdarrenr /* strategy */ nostrategy, 163255332Scy /* name */ "ipf", 164145522Sdarrenr /* maj */ CDEV_MAJOR, 165145522Sdarrenr /* dump */ nodump, 166145522Sdarrenr /* psize */ nopsize, 167145522Sdarrenr /* flags */ 0, 168145522Sdarrenr# if (__FreeBSD_version < 500043) 169145522Sdarrenr /* bmaj */ -1, 170145522Sdarrenr# endif 171255332Scy# if (__FreeBSD_version >= 430000) 172145522Sdarrenr /* kqfilter */ NULL 173170268Sdarrenr# endif 174145522Sdarrenr}; 175139255Sdarrenr#endif 176139255Sdarrenr 177145522Sdarrenrstatic char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME, 178145522Sdarrenr IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL }; 179145522Sdarrenr 180145522Sdarrenr 18154221Sguidostatic int 18254221Sguidoipfilter_modevent(module_t mod, int type, void *unused) 18354221Sguido{ 184145522Sdarrenr int error = 0; 18554221Sguido 186145522Sdarrenr switch (type) 187145522Sdarrenr { 18854221Sguido case MOD_LOAD : 189145522Sdarrenr error = ipf_modload(); 190145522Sdarrenr break; 19160857Sdarrenr 192145522Sdarrenr case MOD_UNLOAD : 193145522Sdarrenr error = ipf_modunload(); 194145522Sdarrenr break; 195145522Sdarrenr default: 196145522Sdarrenr error = EINVAL; 197145522Sdarrenr break; 198145522Sdarrenr } 199145522Sdarrenr return error; 200145522Sdarrenr} 20154221Sguido 20254221Sguido 203145522Sdarrenrstatic int 204145522Sdarrenripf_modload() 205145522Sdarrenr{ 206145522Sdarrenr char *defpass, *c, *str; 207145522Sdarrenr int i, j, error; 20854221Sguido 209255332Scy if (ipf_load_all() != 0) 210255332Scy return EIO; 211170268Sdarrenr 212255332Scy if (ipf_create_all(&ipfmain) == NULL) 213255332Scy return EIO; 214255332Scy 215255332Scy error = ipfattach(&ipfmain); 216255332Scy if (error) 217145522Sdarrenr return error; 21854221Sguido 219145522Sdarrenr for (i = 0; i < IPL_LOGSIZE; i++) 220145522Sdarrenr ipf_devs[i] = NULL; 221145522Sdarrenr 222145522Sdarrenr for (i = 0; (str = ipf_devfiles[i]); i++) { 22354221Sguido c = NULL; 224145522Sdarrenr for(j = strlen(str); j > 0; j--) 225145522Sdarrenr if (str[j] == '/') { 226145522Sdarrenr c = str + j + 1; 22754221Sguido break; 22854221Sguido } 22954221Sguido if (!c) 230145522Sdarrenr c = str; 231255332Scy ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, "%s", c); 232145522Sdarrenr } 23354221Sguido 234172776Sdarrenr error = ipf_pfil_hook(); 235172776Sdarrenr if (error != 0) 236172776Sdarrenr return error; 237172776Sdarrenr ipf_event_reg(); 238172776Sdarrenr 239255332Scy if (FR_ISPASS(ipfmain.ipf_pass)) 240145522Sdarrenr defpass = "pass"; 241255332Scy else if (FR_ISBLOCK(ipfmain.ipf_pass)) 242145522Sdarrenr defpass = "block"; 243255332Scy else 244145522Sdarrenr defpass = "no-match -> block"; 245145522Sdarrenr 246145522Sdarrenr printf("%s initialized. Default = %s all, Logging = %s%s\n", 247255332Scy ipfilter_version, defpass, 248145522Sdarrenr#ifdef IPFILTER_LOG 249145522Sdarrenr "enabled", 250145522Sdarrenr#else 251145522Sdarrenr "disabled", 252145522Sdarrenr#endif 253145522Sdarrenr#ifdef IPFILTER_COMPILED 254145522Sdarrenr " (COMPILED)" 255145522Sdarrenr#else 256145522Sdarrenr "" 257145522Sdarrenr#endif 258255332Scy ); 259145522Sdarrenr return 0; 260145522Sdarrenr} 261145522Sdarrenr 262145522Sdarrenr 263145522Sdarrenrstatic int 264145522Sdarrenripf_modunload() 265145522Sdarrenr{ 266145522Sdarrenr int error, i; 267145522Sdarrenr 268255332Scy if (ipfmain.ipf_refcnt) 269145522Sdarrenr return EBUSY; 270145522Sdarrenr 271255332Scy error = ipf_pfil_unhook(); 272255332Scy if (error != 0) 273255332Scy return error; 274255332Scy 275255332Scy if (ipfmain.ipf_running >= 0) { 276255332Scy error = ipfdetach(&ipfmain); 277145522Sdarrenr if (error != 0) 278145522Sdarrenr return error; 279255332Scy 280255332Scy ipf_destroy_all(&ipfmain); 281255332Scy ipf_unload_all(); 282145522Sdarrenr } else 283145522Sdarrenr error = 0; 284145522Sdarrenr 285255332Scy ipfmain.ipf_running = -2; 286170268Sdarrenr 287145522Sdarrenr for (i = 0; ipf_devfiles[i]; i++) { 288145522Sdarrenr if (ipf_devs[i] != NULL) 289145522Sdarrenr destroy_dev(ipf_devs[i]); 29054221Sguido } 291145522Sdarrenr 292145522Sdarrenr printf("%s unloaded\n", ipfilter_version); 293145522Sdarrenr 29454221Sguido return error; 29554221Sguido} 29654221Sguido 297145522Sdarrenr 29854221Sguidostatic moduledata_t ipfiltermod = { 299145522Sdarrenr "ipfilter", 30054221Sguido ipfilter_modevent, 301241394Skevlo 0 30254221Sguido}; 303145522Sdarrenr 304145522Sdarrenr 30554221SguidoDECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); 306145522Sdarrenr#ifdef MODULE_VERSION 307145522SdarrenrMODULE_VERSION(ipfilter, 1); 308145522Sdarrenr#endif 309145522Sdarrenr 310145522Sdarrenr 311145522Sdarrenr#ifdef SYSCTL_IPF 312145522Sdarrenrint 313145522Sdarrenrsysctl_ipf_int ( SYSCTL_HANDLER_ARGS ) 314145522Sdarrenr{ 315145522Sdarrenr int error = 0; 316145522Sdarrenr 317145522Sdarrenr if (arg1) 318145522Sdarrenr error = SYSCTL_OUT(req, arg1, sizeof(int)); 319145522Sdarrenr else 320145522Sdarrenr error = SYSCTL_OUT(req, &arg2, sizeof(int)); 321145522Sdarrenr 322145522Sdarrenr if (error || !req->newptr) 323145522Sdarrenr return (error); 324145522Sdarrenr 325145522Sdarrenr if (!arg1) 326145522Sdarrenr error = EPERM; 327145522Sdarrenr else { 328255332Scy if ((oidp->oid_kind & CTLFLAG_OFF) && (ipfmain.ipf_running > 0)) 329145522Sdarrenr error = EBUSY; 330145522Sdarrenr else 331145522Sdarrenr error = SYSCTL_IN(req, arg1, sizeof(int)); 332145522Sdarrenr } 333145522Sdarrenr return (error); 334145522Sdarrenr} 335145522Sdarrenr#endif 336161356Sguido 337161356Sguido 338161356Sguidostatic int 339170268Sdarrenr#if __FreeBSD_version >= 500043 340255332Scyipfpoll(struct cdev *dev, int events, struct thread *td) 341170268Sdarrenr#else 342255332Scyipfpoll(dev_t dev, int events, struct proc *td) 343170268Sdarrenr#endif 344161356Sguido{ 345255332Scy int unit = GET_MINOR(dev); 346161356Sguido int revents; 347161356Sguido 348255332Scy if (unit < 0 || unit > IPL_LOGMAX) 349161356Sguido return 0; 350161356Sguido 351161356Sguido revents = 0; 352161356Sguido 353255332Scy switch (unit) 354161356Sguido { 355161356Sguido case IPL_LOGIPF : 356161356Sguido case IPL_LOGNAT : 357161356Sguido case IPL_LOGSTATE : 358161356Sguido#ifdef IPFILTER_LOG 359255332Scy if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&ipfmain, unit)) 360161356Sguido revents |= events & (POLLIN | POLLRDNORM); 361255332Scy#endif 362161356Sguido break; 363161356Sguido case IPL_LOGAUTH : 364255332Scy if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&ipfmain)) 365161356Sguido revents |= events & (POLLIN | POLLRDNORM); 366255332Scy break; 367161356Sguido case IPL_LOGSYNC : 368255332Scy if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&ipfmain)) 369161356Sguido revents |= events & (POLLIN | POLLRDNORM); 370255332Scy if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&ipfmain)) 371161356Sguido revents |= events & (POLLOUT | POLLWRNORM); 372161356Sguido break; 373161356Sguido case IPL_LOGSCAN : 374161356Sguido case IPL_LOGLOOKUP : 375161356Sguido default : 376161356Sguido break; 377161356Sguido } 378161356Sguido 379161356Sguido if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0)) 380255332Scy selrecord(td, &ipfmain.ipf_selwait[unit]); 381161356Sguido 382161356Sguido return revents; 383161356Sguido} 384255332Scy 385255332Scy 386255332Scy/* 387255332Scy * routines below for saving IP headers to buffer 388255332Scy */ 389255332Scystatic int ipfopen(dev, flags 390255332Scy#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) 391255332Scy, devtype, p) 392255332Scy int devtype; 393255332Scy# if (__FreeBSD_version >= 500024) 394255332Scy struct thread *p; 395255332Scy# else 396255332Scy struct proc *p; 397255332Scy# endif /* __FreeBSD_version >= 500024 */ 398255332Scy#else 399255332Scy) 400255332Scy#endif 401255332Scy#if (__FreeBSD_version >= 502116) 402255332Scy struct cdev *dev; 403255332Scy#else 404255332Scy dev_t dev; 405255332Scy#endif 406255332Scy int flags; 407255332Scy{ 408255332Scy int unit = GET_MINOR(dev); 409255332Scy int error; 410255332Scy 411255332Scy if (IPL_LOGMAX < unit) 412255332Scy error = ENXIO; 413255332Scy else { 414255332Scy switch (unit) 415255332Scy { 416255332Scy case IPL_LOGIPF : 417255332Scy case IPL_LOGNAT : 418255332Scy case IPL_LOGSTATE : 419255332Scy case IPL_LOGAUTH : 420255332Scy case IPL_LOGLOOKUP : 421255332Scy case IPL_LOGSYNC : 422255332Scy#ifdef IPFILTER_SCAN 423255332Scy case IPL_LOGSCAN : 424255332Scy#endif 425255332Scy error = 0; 426255332Scy break; 427255332Scy default : 428255332Scy error = ENXIO; 429255332Scy break; 430255332Scy } 431255332Scy } 432255332Scy return error; 433255332Scy} 434255332Scy 435255332Scy 436255332Scystatic int ipfclose(dev, flags 437255332Scy#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) 438255332Scy, devtype, p) 439255332Scy int devtype; 440255332Scy# if (__FreeBSD_version >= 500024) 441255332Scy struct thread *p; 442255332Scy# else 443255332Scy struct proc *p; 444255332Scy# endif /* __FreeBSD_version >= 500024 */ 445255332Scy#else 446255332Scy) 447255332Scy#endif 448255332Scy#if (__FreeBSD_version >= 502116) 449255332Scy struct cdev *dev; 450255332Scy#else 451255332Scy dev_t dev; 452255332Scy#endif 453255332Scy int flags; 454255332Scy{ 455255332Scy int unit = GET_MINOR(dev); 456255332Scy 457255332Scy if (IPL_LOGMAX < unit) 458255332Scy unit = ENXIO; 459255332Scy else 460255332Scy unit = 0; 461255332Scy return unit; 462255332Scy} 463255332Scy 464255332Scy/* 465255332Scy * ipfread/ipflog 466255332Scy * both of these must operate with at least splnet() lest they be 467255332Scy * called during packet processing and cause an inconsistancy to appear in 468255332Scy * the filter lists. 469255332Scy */ 470255332Scy#if (BSD >= 199306) 471255332Scystatic int ipfread(dev, uio, ioflag) 472255332Scy int ioflag; 473255332Scy#else 474255332Scystatic int ipfread(dev, uio) 475255332Scy#endif 476255332Scy#if (__FreeBSD_version >= 502116) 477255332Scy struct cdev *dev; 478255332Scy#else 479255332Scy dev_t dev; 480255332Scy#endif 481255332Scy struct uio *uio; 482255332Scy{ 483255332Scy int unit = GET_MINOR(dev); 484255332Scy 485255332Scy if (unit < 0) 486255332Scy return ENXIO; 487255332Scy 488255332Scy if (ipfmain.ipf_running < 1) 489255332Scy return EIO; 490255332Scy 491255332Scy if (unit == IPL_LOGSYNC) 492255332Scy return ipf_sync_read(&ipfmain, uio); 493255332Scy 494255332Scy#ifdef IPFILTER_LOG 495255332Scy return ipf_log_read(&ipfmain, unit, uio); 496255332Scy#else 497255332Scy return ENXIO; 498255332Scy#endif 499255332Scy} 500255332Scy 501255332Scy 502255332Scy/* 503255332Scy * ipfwrite 504255332Scy * both of these must operate with at least splnet() lest they be 505255332Scy * called during packet processing and cause an inconsistancy to appear in 506255332Scy * the filter lists. 507255332Scy */ 508255332Scy#if (BSD >= 199306) 509255332Scystatic int ipfwrite(dev, uio, ioflag) 510255332Scy int ioflag; 511255332Scy#else 512255332Scystatic int ipfwrite(dev, uio) 513255332Scy#endif 514255332Scy#if (__FreeBSD_version >= 502116) 515255332Scy struct cdev *dev; 516255332Scy#else 517255332Scy dev_t dev; 518255332Scy#endif 519255332Scy struct uio *uio; 520255332Scy{ 521255332Scy 522255332Scy if (ipfmain.ipf_running < 1) 523255332Scy return EIO; 524255332Scy 525255332Scy if (GET_MINOR(dev) == IPL_LOGSYNC) 526255332Scy return ipf_sync_write(&ipfmain, uio); 527255332Scy return ENXIO; 528255332Scy} 529